[cfe-dev] Proposal for thread safety attributes for Clang

Caitlin Sadowski supertri at google.com
Mon Jul 11 16:19:30 PDT 2011


Bjorn,

There are many reasons why not to use templates for a similar thread
safety analysis. These issues include the fact that templates can
complicate the program, but may not be able to handle more complicated
locking scenarios. Given a particular locking strategy, the use of
templates forces the specification of that strategy to be closely tied
to the implementation details. If we wished to change how locking
works in a piece of code, the template system may not easily support
the new mechanism. Also, templates do not work for C code.

The attribute-based system provides an extensible way of supporting
future work, such as running more advanced analyses with the static
analyzer framework, new types of annotations that may be difficult to
implement with templates (such as cooperability yield points [1, 2]),
and annotation inference.

We have some evidence that this approach works well: we previously
implemented this proposal in GCC, and the use of attributes allowed us
to annotate large parts of Google's pre-existing codebase without
having to rearchitect it.

Cheers,
Caitlin

[1] Effects for Cooperable and Serializable Threads. Jaeheon Yi and
Cormac Flanagan. Workshop on types in Language Design and
Implementation (TLDI) 2010.
[2] Applying Usability Studies to Correctness Conditions: A Case Study
of Cooperability. Caitlin Sadowski and Jaeheon Yi. Onward! Workshop on
Evaluation and Usability of Programming Languages and Tools (PLATEAU),
2010.


On Sat, Jul 2, 2011 at 2:24 AM, Bjorn Reese <breese at mail1.stofanet.dk> wrote:
>
> Caitlin.
>
> The two problems you address can be handled with templates instead of
> annotations. While the techniques mentioned below do not solve all
> thread-safety problems, they do solve the most common ones that I have
> encountered. And none of them requires extensions to the compiler.
>
> ACQUIRED_AFTER: Some deadlocks occur because you need to lock two
> mutexes, A and B, and you accidentially lock A before B in one function
> and B before A in another function. Such deadlocks can be avoided with
> the Boost.Thread locking functions [1], as it guarantees that a list of
> mutexes always is locked in the same order, regardless of the order you
> list them.
>
> GUARDED_BY: It is true that the C++ compiler does not know which mutex
> guards what variables, and therefore cannot alert you if you, say, use
> a variable without locking its mutex. I solved this problem in a
> commercial project by defining two templates: a guard and an accessor.
> The guard contained the mutex and the variable (or struct of
> variables) as a private member, and only the accessor could access it.
> The accessor would lock and unlock the mutex in a RAII manner. An
> example using this technique could look like this:
>
>  class Alpha
>  {
>  public:
>    int GetValue() const
>    {
>      const_unique_access<int> value(valueGuard);
>      return *value;
>    }
>    void SetValue(int v)
>    {
>      unique_access<int> value(valueGuard);
>      *value = v;
>    }
>  private:
>    unique_access_guard<int> valueGuard;
>  };
>
> This solution shares some traits with Anthony Williams' Synchronized
> Values [2].
>
> [1] http://www.boost.org/doc/libs/1_46_1/doc/html/thread/synchronization.html#thread.synchronization.lock_functions
> [2] http://drdobbs.com/cpp/225200269




More information about the cfe-dev mailing list