
======================
Thread Safety Analysis
======================

Introduction
============

Clang Thread Safety Analysis is a C++ language extension which warns about
potential race conditions in code.  The analysis is completely static (i.e.
compile-time); there is no run-time overhead.  The analysis is still
under active development, but it is mature enough to be deployed in an
industrial setting.  It is being developed by Google, in collaboration with
CERT/SEI, and is used extensively in Google's internal code base.

Thread safety analysis works very much like a type system for multi-threaded
programs.  In addition to declaring the *type* of data (e.g. ``int``, ``float``,
etc.), the programmer can (optionally) declare how access to that data is
controlled in a multi-threaded environment.  For example, if ``foo`` is
*guarded by* the mutex ``mu``, then the analysis will issue a warning whenever
a piece of code reads or writes to ``foo`` without first locking ``mu``.
Similarly, if there are particular routines that should only be called by
the GUI thread, then the analysis will warn if other threads call those
routines.

Getting Started
----------------

.. code-block:: c++

  #include "mutex.h"

  class BankAccount {
  private:
    Mutex mu;
    int   balance GUARDED_BY(mu);

    void depositImpl(int amount) {
      balance += amount;       // WARNING! Cannot write balance without locking mu.
    }

    void withdrawImpl(int amount) REQUIRES(mu) {
      balance -= amount;       // OK. Caller must have locked mu.
    }

  public:
    void withdraw(int amount) {
      mu.Lock();
      withdrawImpl(amount);    // OK.  We've locked mu.
    }                          // WARNING!  Failed to unlock mu.

    void transferFrom(BankAccount& b, int amount) {
      mu.Lock();
      b.withdrawImpl(amount);  // WARNING!  Calling withdrawImpl() requires locking b.mu.
      depositImpl(amount);     // OK.  depositImpl() has no requirements.
      mu.Unlock();
    }
  };

This example demonstrates the basic concepts behind the analysis.  The
``GUARDED_BY`` attribute declares that a thread must lock ``mu`` before it can
read or write to ``balance``, thus ensuring that the increment and decrement
operations are atomic.  Similarly, ``REQUIRES`` declares that
the calling thread must lock ``mu`` before calling ``withdrawImpl``.
Because the caller is assumed to have locked ``mu``, it is safe to modify
``balance`` within the body of the method.

The ``depositImpl()`` method does not have ``REQUIRES``, so the
analysis issues a warning.  Thread safety analysis is not inter-procedural, so
caller requirements must be explicitly declared.
There is also a warning in ``transferFrom()``, because although the method
locks ``this->mu``, it does not lock ``b.mu``.  The analysis understands
that these are two separate mutexes, in two different objects.

Finally, there is a warning in the ``withdraw()`` method, because it fails to
unlock ``mu``.  Every lock must have a corresponding unlock, and the analysis
will detect both double locks, and double unlocks.  A function is allowed to
acquire a lock without releasing it, (or vice versa), but it must be annotated
as such (using ``ACQUIRE``/``RELEASE``).


Running The Analysis
--------------------

To run the analysis, simply compile with the ``-Wthread-safety`` flag, e.g.

.. code-block:: bash

  clang -c -Wthread-safety example.cpp

Note that this example assumes the presence of a suitably annotated
:ref:`mutexheader` that declares which methods perform locking,
unlocking, and so on.


Basic Concepts: Capabilities
============================

Thread safety analysis provides a way of protecting *resources* with
*capabilities*.  A resource is either a data member, or a function/method
that provides access to some underlying resource.  The analysis ensures that
the calling thread cannot access the *resource* (i.e. call the function, or
read/write the data) unless it has the *capability* to do so.

Capabilities are associated with named C++ objects which declare specific
methods to acquire and release the capability.  The name of the object serves
to identify the capability.  The most common example is a mutex.  For example,
if ``mu`` is a mutex, then calling ``mu.Lock()`` causes the calling thread
to acquire the capability to access data that is protected by ``mu``. Similarly,
calling ``mu.Unlock()`` releases that capability.

A thread may hold a capability either *exclusively* or *shared*.  An exclusive
capability can be held by only one thread at a time, while a shared capability
can be held by many threads at the same time.  This mechanism enforces a
multiple-reader, single-writer pattern.  Write operations to protected data
require exclusive access, while read operations require only shared access.

At any given moment during program execution, a thread holds a specific set of
capabilities (e.g. the set of mutexes that it has locked.)  These act like keys
or tokens that allow the thread to access a given resource.  Just like physical
security keys, a thread cannot make copy of a capability, nor can it destroy
one.  A thread can only release a capability to another thread, or acquire one
from another thread.  The annotations are deliberately agnostic about the
exact mechanism used to acquire and release capabilities; it assumes that the
underlying implementation (e.g. the Mutex implementation) does the handoff in
an appropriate manner.

The set of capabilities that are actually held by a given thread at a given
point in program execution is a run-time concept.  The static analysis works
by calculating an approximation of that set, called the *capability
environment*.  The capability environment is calculated for every program point,
and describes the set of capabilities that are statically known to be held, or
not held, at that particular point.  This environment is a conservative
approximation of the full set of capabilities that will actually held by a
thread at run-time.


Reference Guide
===============

The thread safety analysis uses attributes to declare threading constraints.
Attributes must be attached to named declarations, such as classes, methods,
and data members. Users are *strongly advised* to define macros for the various
attributes; example definitions can be found in :ref:`mutexheader`, below.
The following documentation assumes the use of macros.

For historical reasons, prior versions of thread safety used macro names that
were very lock-centric.  These macros have since been renamed to fit a more
general capability model.  The prior names are still in use, and will be
mentioned under the tag *previously* where appropriate.


GUARDED_BY(c) and PT_GUARDED_BY(c)
----------------------------------

``GUARDED_BY`` is an attribute on data members, which declares that the data
member is protected by the given capability.  Read operations on the data
require shared access, while write operations require exclusive access.

``PT_GUARDED_BY`` is similar, but is intended for use on pointers and smart
pointers. There is no constraint on the data member itself, but the *data that
it points to* is protected by the given capability.

.. code-block:: c++

  Mutex mu;
  int *p1             GUARDED_BY(mu);
  int *p2             PT_GUARDED_BY(mu);
  unique_ptr<int> p3  PT_GUARDED_BY(mu);

  void test() {
    p1 = 0;             // Warning!

    *p2 = 42;           // Warning!
    p2 = new int;       // OK.

    *p3 = 42;           // Warning!
    p3.reset(new int);  // OK.
  }


REQUIRES(...), REQUIRES_SHARED(...)
-----------------------------------

*Previously*: ``EXCLUSIVE_LOCKS_REQUIRED``, ``SHARED_LOCKS_REQUIRED``

``REQUIRES`` is an attribute on functions or methods, which
declares that the calling thread must have exclusive access to the given
capabilities.  More than one capability may be specified.  The capabilities
must be held on entry to the function, *and must still be held on exit*.

``REQUIRES_SHARED`` is similar, but requires only shared access.

.. code-block:: c++

  Mutex mu1, mu2;
  int a GUARDED_BY(mu1);
  int b GUARDED_BY(mu2);

  void foo() REQUIRES(mu1, mu2) {
    a = 0;
    b = 0;
  }

  void test() {
    mu1.Lock();
    foo();         // Warning!  Requires mu2.
    mu1.Unlock();
  }


ACQUIRE(...), ACQUIRE_SHARED(...), RELEASE(...), RELEASE_SHARED(...)
--------------------------------------------------------------------

*Previously*: ``EXCLUSIVE_LOCK_FUNCTION``, ``SHARED_LOCK_FUNCTION``,
``UNLOCK_FUNCTION``

``ACQUIRE`` is an attribute on functions or methods, which
declares that the function acquires a capability, but does not release it.  The
caller must not hold the given capability on entry, and it will hold the
capability on exit.  ``ACQUIRE_SHARED`` is similar.

``RELEASE`` and ``RELEASE_SHARED`` declare that the function releases the given
capability.  The caller must hold the capability on entry, and will no longer
hold it on exit. It does not matter whether the given capability is shared or
exclusive.

.. code-block:: c++

  Mutex mu;
  MyClass myObject GUARDED_BY(mu);

  void lockAndInit() ACQUIRE(mu) {
    mu.Lock();
    myObject.init();
  }

  void cleanupAndUnlock() RELEASE(mu) {
    myObject.cleanup();
  }                          // Warning!  Need to unlock mu.

  void test() {
    lockAndInit();
    myObject.doSomething();
    cleanupAndUnlock();
    myObject.doSomething();  // Warning, mu is not locked.
  }

If no argument is passed to ``ACQUIRE`` or ``RELEASE``, then the argument is
assumed to be ``this``, and the analysis will not check the body of the
function.  This pattern is intended for use by classes which hide locking
details behind an abstract interface.  For example:

.. code-block:: c++

  template <class T>
  class CAPABILITY("mutex") Container {
  private:
    Mutex mu;
    T* data;

  public:
    // Hide mu from public interface.
    void Lock()   ACQUIRE() { mu.Lock(); }
    void Unlock() RELEASE() { mu.Unlock(); }

    T& getElem(int i) { return data[i]; }
  };

  void test() {
    Container<int> c;
    c.Lock();
    int i = c.getElem(0);
    c.Unlock();
  }


EXCLUDES(...)
-------------

*Previously*: ``LOCKS_EXCLUDED``

``EXCLUDES`` is an attribute on functions or methods, which declares that
the caller must *not* hold the given capabilities.  This annotation is
used to prevent deadlock.  Many mutex implementations are not re-entrant, so
deadlock can occur if the function acquires the mutex a second time.

.. code-block:: c++

  Mutex mu;
  int a GUARDED_BY(mu);

  void clear() EXCLUDES(mu) {
    mu.Lock();
    a = 0;
    mu.Unlock();
  }

  void reset() {
    mu.Lock();
    clear();     // Warning!  Caller cannot hold 'mu'.
    mu.Unlock();
  }

Unlike ``REQUIRES``, ``EXCLUDES`` is optional.  The analysis will not issue a
warning if the attribute is missing, which can lead to false negatives in some
cases.  This issue is discussed further in :ref:`negative`.


NO_THREAD_SAFETY_ANALYSIS
-------------------------

``NO_THREAD_SAFETY_ANALYSIS`` is an attribute on functions or methods, which
turns off thread safety checking for that method.  It provides an escape hatch
for functions which are either (1) deliberately thread-unsafe, or (2) are
thread-safe, but too complicated for the analysis to understand.  Reasons for
(2) will be described in the :ref:`limitations`, below.

.. code-block:: c++

  class Counter {
    Mutex mu;
    int a GUARDED_BY(mu);

    void unsafeIncrement() NO_THREAD_SAFETY_ANALYSIS { a++; }
  };

Unlike the other attributes, NO_THREAD_SAFETY_ANALYSIS is not part of the
interface of a function, and should thus be placed on the function definition
(in the ``.cc`` or ``.cpp`` file) rather than on the function declaration
(in the header).


RETURN_CAPABILITY(c)
--------------------

*Previously*: ``LOCK_RETURNED``

``RETURN_CAPABILITY`` is an attribute on functions or methods, which declares
that the function returns a reference to the given capability.  It is used to
annotate getter methods that return mutexes.

.. code-block:: c++

  class MyClass {
  private:
    Mutex mu;
    int a GUARDED_BY(mu);

  public:
    Mutex* getMu() RETURN_CAPABILITY(mu) { return &mu; }

    // analysis knows that getMu() == mu
    void clear() REQUIRES(getMu()) { a = 0; }
  };


ACQUIRED_BEFORE(...), ACQUIRED_AFTER(...)
-----------------------------------------

``ACQUIRED_BEFORE`` and ``ACQUIRED_AFTER`` are attributes on member
declarations, specifically declarations of mutexes or other capabilities.
These declarations enforce a particular order in which the mutexes must be
acquired, in order to prevent deadlock.

.. code-block:: c++

  Mutex m1;
  Mutex m2 ACQUIRED_AFTER(m1);

  // Alternative declaration
  // Mutex m2;
  // Mutex m1 ACQUIRED_BEFORE(m2);

  void foo() {
    m2.Lock();
    m1.Lock();  // Warning!  m2 must be acquired after m1.
    m1.Unlock();
    m2.Unlock();
  }


CAPABILITY(<string>)
--------------------

*Previously*: ``LOCKABLE``

``CAPABILITY`` is an attribute on classes, which specifies that objects of the
class can be used as a capability.  The string argument specifies the kind of
capability in error messages, e.g. ``"mutex"``.  See the ``Container`` example
given above, or the ``Mutex`` class in :ref:`mutexheader`.


SCOPED_CAPABILITY
-----------------

*Previously*: ``SCOPED_LOCKABLE``

``SCOPED_CAPABILITY`` is an attribute on classes that implement RAII-style
locking, in which a capability is acquired in the constructor, and released in
the destructor.  Such classes require special handling because the constructor
and destructor refer to the capability via different names; see the
``MutexLocker`` class in :ref:`mutexheader`, below.


TRY_ACQUIRE(<bool>, ...), TRY_ACQUIRE_SHARED(<bool>, ...)
---------------------------------------------------------

*Previously:* ``EXCLUSIVE_TRYLOCK_FUNCTION``, ``SHARED_TRYLOCK_FUNCTION``

These are attributes on a function or method that tries to acquire the given
capability, and returns a boolean value indicating success or failure.
The first argument must be ``true`` or ``false``, to specify which return value
indicates success, and the remaining arguments are interpreted in the same way
as ``ACQUIRE``.  See :ref:`mutexheader`, below, for example uses.


ASSERT_CAPABILITY(...) and ASSERT_SHARED_CAPABILITY(...)
--------------------------------------------------------

*Previously:*  ``ASSERT_EXCLUSIVE_LOCK``, ``ASSERT_SHARED_LOCK``

These are attributes on a function or method that does a run-time test to see
whether the calling thread holds the given capability.  The function is assumed
to fail (no return) if the capability is not held.  See :ref:`mutexheader`,
below, for example uses.


GUARDED_VAR and PT_GUARDED_VAR
------------------------------

Use of these attributes has been deprecated.


Warning flags
-------------

* ``-Wthread-safety``:  Umbrella flag which turns on the following three:

  + ``-Wthread-safety-attributes``: Sanity checks on attribute syntax.
  + ``-Wthread-safety-analysis``: The core analysis.
  + ``-Wthread-safety-precise``: Requires that mutex expressions match precisely.
       This warning can be disabled for code which has a lot of aliases.
  + ``-Wthread-safety-reference``: Checks when guarded members are passed by reference.


:ref:`negative` are an experimental feature, which are enabled with:

* ``-Wthread-safety-negative``:  Negative capabilities.  Off by default.

When new features and checks are added to the analysis, they can often introduce
additional warnings.  Those warnings are initially released as *beta* warnings
for a period of time, after which they are migrated into the standard analysis.

* ``-Wthread-safety-beta``:  New features.  Off by default.


.. _negative:

Negative Capabilities
=====================

Thread Safety Analysis is designed to prevent both race conditions and
deadlock.  The GUARDED_BY and REQUIRES attributes prevent race conditions, by
ensuring that a capability is held before reading or writing to guarded data,
and the EXCLUDES attribute prevents deadlock, by making sure that a mutex is
*not* held.

However, EXCLUDES is an optional attribute, and does not provide the same
safety guarantee as REQUIRES.  In particular:

  * A function which acquires a capability does not have to exclude it.
  * A function which calls a function that excludes a capability does not
    have transitively exclude that capability.

As a result, EXCLUDES can easily produce false negatives:

.. code-block:: c++

  class Foo {
    Mutex mu;

    void foo() {
      mu.Lock();
      bar();           // No warning.
      baz();           // No warning.
      mu.Unlock();
    }

    void bar() {       // No warning.  (Should have EXCLUDES(mu)).
      mu.Lock();
      // ...
      mu.Unlock();
    }

    void baz() {
      bif();           // No warning.  (Should have EXCLUDES(mu)).
    }

    void bif() EXCLUDES(mu);
  };


Negative requirements are an alternative EXCLUDES that provide
a stronger safety guarantee.  A negative requirement uses the  REQUIRES
attribute, in conjunction with the ``!`` operator, to indicate that a capability
should *not* be held.

For example, using ``REQUIRES(!mu)`` instead of ``EXCLUDES(mu)`` will produce
the appropriate warnings:

.. code-block:: c++

  class FooNeg {
    Mutex mu;

    void foo() REQUIRES(!mu) {   // foo() now requires !mu.
      mu.Lock();
      bar();
      baz();
      mu.Unlock();
    }

    void bar() {
      mu.Lock();       // WARNING!  Missing REQUIRES(!mu).
      // ...
      mu.Unlock();
    }

    void baz() {
      bif();           // WARNING!  Missing REQUIRES(!mu).
    }

    void bif() REQUIRES(!mu);
  };


Negative requirements are an experimental feature which is off by default,
because it will produce many warnings in existing code.  It can be enabled
by passing ``-Wthread-safety-negative``.


.. _faq:

Frequently Asked Questions
==========================

(Q) Should I put attributes in the header file, or in the .cc/.cpp/.cxx file?

(A) Attributes are part of the formal interface of a function, and should
always go in the header, where they are visible to anything that includes
the header.  Attributes in the .cpp file are not visible outside of the
immediate translation unit, which leads to false negatives and false positives.


(Q) "*Mutex is not locked on every path through here?*"  What does that mean?

(A) See :ref:`conditional_locks`, below.


.. _limitations:

Known Limitations
=================

Lexical scope
-------------

Thread safety attributes contain ordinary C++ expressions, and thus follow
ordinary C++ scoping rules.  In particular, this means that mutexes and other
capabilities must be declared before they can be used in an attribute.
Use-before-declaration is okay within a single class, because attributes are
parsed at the same time as method bodies. (C++ delays parsing of method bodies
until the end of the class.)  However, use-before-declaration is not allowed
between classes, as illustrated below.

.. code-block:: c++

  class Foo;

  class Bar {
    void bar(Foo* f) REQUIRES(f->mu);  // Error: mu undeclared.
  };

  class Foo {
    Mutex mu;
  };


Private Mutexes
---------------

Good software engineering practice dictates that mutexes should be private
members, because the locking mechanism used by a thread-safe class is part of
its internal implementation.  However, private mutexes can sometimes leak into
the public interface of a class.
Thread safety attributes follow normal C++ access restrictions, so if ``mu``
is a private member of ``c``, then it is an error to write ``c.mu`` in an
attribute.

One workaround is to (ab)use the ``RETURN_CAPABILITY`` attribute to provide a
public *name* for a private mutex, without actually exposing the underlying
mutex.  For example:

.. code-block:: c++

  class MyClass {
  private:
    Mutex mu;

  public:
    // For thread safety analysis only.  Does not actually return mu.
    Mutex* getMu() RETURN_CAPABILITY(mu) { return 0; }

    void doSomething() REQUIRES(mu);
  };

  void doSomethingTwice(MyClass& c) REQUIRES(c.getMu()) {
    // The analysis thinks that c.getMu() == c.mu
    c.doSomething();
    c.doSomething();
  }

In the above example, ``doSomethingTwice()`` is an external routine that
requires ``c.mu`` to be locked, which cannot be declared directly because ``mu``
is private.  This pattern is discouraged because it
violates encapsulation, but it is sometimes necessary, especially when adding
annotations to an existing code base.  The workaround is to define ``getMu()``
as a fake getter method, which is provided only for the benefit of thread
safety analysis.


.. _conditional_locks:

No conditionally held locks.
----------------------------

The analysis must be able to determine whether a lock is held, or not held, at
every program point.  Thus, sections of code where a lock *might be held* will
generate spurious warnings (false positives).  For example:

.. code-block:: c++

  void foo() {
    bool b = needsToLock();
    if (b) mu.Lock();
    ...  // Warning!  Mutex 'mu' is not held on every path through here.
    if (b) mu.Unlock();
  }


No checking inside constructors and destructors.
------------------------------------------------

The analysis currently does not do any checking inside constructors or
destructors.  In other words, every constructor and destructor is treated as
if it was annotated with ``NO_THREAD_SAFETY_ANALYSIS``.
The reason for this is that during initialization, only one thread typically
has access to the object which is being initialized, and it is thus safe (and
common practice) to initialize guarded members without acquiring any locks.
The same is true of destructors.

Ideally, the analysis would allow initialization of guarded members inside the
object being initialized or destroyed, while still enforcing the usual access
restrictions on everything else.  However, this is difficult to enforce in
practice, because in complex pointer-based data structures, it is hard to
determine what data is owned by the enclosing object.

No inlining.
------------

Thread safety analysis is strictly intra-procedural, just like ordinary type
checking.  It relies only on the declared attributes of a function, and will
not attempt to inline any method calls.  As a result, code such as the
following will not work:

.. code-block:: c++

  template<class T>
  class AutoCleanup {
    T* object;
    void (T::*mp)();

  public:
    AutoCleanup(T* obj, void (T::*imp)()) : object(obj), mp(imp) { }
    ~AutoCleanup() { (object->*mp)(); }
  };

  Mutex mu;
  void foo() {
    mu.Lock();
    AutoCleanup<Mutex>(&mu, &Mutex::Unlock);
    // ...
  }  // Warning, mu is not unlocked.

In this case, the destructor of ``Autocleanup`` calls ``mu.Unlock()``, so
the warning is bogus.  However,
thread safety analysis cannot see the unlock, because it does not attempt to
inline the destructor.  Moreover, there is no way to annotate the destructor,
because the destructor is calling a function that is not statically known.
This pattern is simply not supported.


No alias analysis.
------------------

The analysis currently does not track pointer aliases.  Thus, there can be
false positives if two pointers both point to the same mutex.


.. code-block:: c++

  class MutexUnlocker {
    Mutex* mu;

  public:
    MutexUnlocker(Mutex* m) RELEASE(m) : mu(m)  { mu->Unlock(); }
    ~MutexUnlocker() ACQUIRE(mu) { mu->Lock(); }
  };

  Mutex mutex;
  void test() REQUIRES(mutex) {
    {
      MutexUnlocker munl(&mutex);  // unlocks mutex
      doSomeIO();
    }                              // Warning: locks munl.mu
  }

The MutexUnlocker class is intended to be the dual of the MutexLocker class,
defined in :ref:`mutexheader`.  However, it doesn't work because the analysis
doesn't know that munl.mu == mutex.  The SCOPED_CAPABILITY attribute handles
aliasing for MutexLocker, but does so only for that particular pattern.


ACQUIRED_BEFORE(...) and ACQUIRED_AFTER(...) are currently unimplemented.
-------------------------------------------------------------------------

To be fixed in a future update.


.. _mutexheader:

mutex.h
=======

Thread safety analysis can be used with any threading library, but it does
require that the threading API be wrapped in classes and methods which have the
appropriate annotations.  The following code provides ``mutex.h`` as an example;
these methods should be filled in to call the appropriate underlying
implementation.


.. code-block:: c++


  #ifndef THREAD_SAFETY_ANALYSIS_MUTEX_H
  #define THREAD_SAFETY_ANALYSIS_MUTEX_H

  // Enable thread safety attributes only with clang.
  // The attributes can be safely erased when compiling with other compilers.
  #if defined(__clang__) && (!defined(SWIG))
  #define THREAD_ANNOTATION_ATTRIBUTE__(x)   __attribute__((x))
  #else
  #define THREAD_ANNOTATION_ATTRIBUTE__(x)   // no-op
  #endif

  #define CAPABILITY(x) \
    THREAD_ANNOTATION_ATTRIBUTE__(capability(x))

  #define SCOPED_CAPABILITY \
    THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)

  #define GUARDED_BY(x) \
    THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))

  #define PT_GUARDED_BY(x) \
    THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))

  #define ACQUIRED_BEFORE(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))

  #define ACQUIRED_AFTER(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))

  #define REQUIRES(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))

  #define REQUIRES_SHARED(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))

  #define ACQUIRE(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))

  #define ACQUIRE_SHARED(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))

  #define RELEASE(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))

  #define RELEASE_SHARED(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))

  #define TRY_ACQUIRE(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))

  #define TRY_ACQUIRE_SHARED(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))

  #define EXCLUDES(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))

  #define ASSERT_CAPABILITY(x) \
    THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))

  #define ASSERT_SHARED_CAPABILITY(x) \
    THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))

  #define RETURN_CAPABILITY(x) \
    THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))

  #define NO_THREAD_SAFETY_ANALYSIS \
    THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)


  // Defines an annotated interface for mutexes.
  // These methods can be implemented to use any internal mutex implementation.
  class CAPABILITY("mutex") Mutex {
  public:
    // Acquire/lock this mutex exclusively.  Only one thread can have exclusive
    // access at any one time.  Write operations to guarded data require an
    // exclusive lock.
    void Lock() ACQUIRE();

    // Acquire/lock this mutex for read operations, which require only a shared
    // lock.  This assumes a multiple-reader, single writer semantics.  Multiple
    // threads may acquire the mutex simultaneously as readers, but a writer
    // must wait for all of them to release the mutex before it can acquire it
    // exclusively.
    void ReaderLock() ACQUIRE_SHARED();

    // Release/unlock an exclusive mutex.
    void Unlock() RELEASE();

    // Release/unlock a shared mutex.
    void ReaderUnlock() RELEASE_SHARED();

    // Try to acquire the mutex.  Returns true on success, and false on failure.
    bool TryLock() TRY_ACQUIRE(true);

    // Try to acquire the mutex for read operations.
    bool ReaderTryLock() TRY_ACQUIRE_SHARED(true);

    // Assert that this mutex is currently held by the calling thread.
    void AssertHeld() ASSERT_CAPABILITY(this);

    // Assert that is mutex is currently held for read operations.
    void AssertReaderHeld() ASSERT_SHARED_CAPABILITY(this);
    
    // For negative capabilities.
    const Mutex& operator!() const { return *this; }
  };


  // MutexLocker is an RAII class that acquires a mutex in its constructor, and
  // releases it in its destructor.
  class SCOPED_CAPABILITY MutexLocker {
  private:
    Mutex* mut;

  public:
    MutexLocker(Mutex *mu) ACQUIRE(mu) : mut(mu) {
      mu->Lock();
    }
    ~MutexLocker() RELEASE() {
      mut->Unlock();
    }
  };


  #ifdef USE_LOCK_STYLE_THREAD_SAFETY_ATTRIBUTES
  // The original version of thread safety analysis the following attribute
  // definitions.  These use a lock-based terminology.  They are still in use
  // by existing thread safety code, and will continue to be supported.

  // Deprecated.
  #define PT_GUARDED_VAR \
    THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_var)

  // Deprecated.
  #define GUARDED_VAR \
    THREAD_ANNOTATION_ATTRIBUTE__(guarded_var)

  // Replaced by REQUIRES
  #define EXCLUSIVE_LOCKS_REQUIRED(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__))

  // Replaced by REQUIRES_SHARED
  #define SHARED_LOCKS_REQUIRED(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__))

  // Replaced by CAPABILITY
  #define LOCKABLE \
    THREAD_ANNOTATION_ATTRIBUTE__(lockable)

  // Replaced by SCOPED_CAPABILITY
  #define SCOPED_LOCKABLE \
    THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)

  // Replaced by ACQUIRE
  #define EXCLUSIVE_LOCK_FUNCTION(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))

  // Replaced by ACQUIRE_SHARED
  #define SHARED_LOCK_FUNCTION(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__))

  // Replaced by RELEASE and RELEASE_SHARED
  #define UNLOCK_FUNCTION(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))

  // Replaced by TRY_ACQUIRE
  #define EXCLUSIVE_TRYLOCK_FUNCTION(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))

  // Replaced by TRY_ACQUIRE_SHARED
  #define SHARED_TRYLOCK_FUNCTION(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__))

  // Replaced by ASSERT_CAPABILITY
  #define ASSERT_EXCLUSIVE_LOCK(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__))

  // Replaced by ASSERT_SHARED_CAPABILITY
  #define ASSERT_SHARED_LOCK(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_lock(__VA_ARGS__))

  // Replaced by EXCLUDE_CAPABILITY.
  #define LOCKS_EXCLUDED(...) \
    THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))

  // Replaced by RETURN_CAPABILITY
  #define LOCK_RETURNED(x) \
    THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))

  #endif  // USE_LOCK_STYLE_THREAD_SAFETY_ATTRIBUTES

  #endif  // THREAD_SAFETY_ANALYSIS_MUTEX_H

