[cfe-dev] Thread safety analysis: escape hatches

Delesley Hutchins delesley at google.com
Fri Sep 7 15:53:23 PDT 2012


I've implemented a new feature in clang's thread safety analysis, and
was looking for any feedback that folks might have as to whether this
is the right approach.

Thread safety analysis currently supports NO_THREAD_SAFETY_ANALYSIS as
an escape hatch for methods that violate thread safety rules.  Adding
NO_THREAD_SAFETY_ANALYSIS as an attribute on a method or function will
turn off checking for that particular method.  However, it is often
the case that you don't want to turn off thread safety for an entire
method, but just for a particular racy line.  For example:

class Foo {
  Mutex mu_;
  int data_ GUARDED_BY(mu_);
  void foo();
};

void foo() {
  mu_.Lock();
  data_ = computeSomeData();
  mu_.Unlock();

  beginNoWarnOnReads();
  // Thread safety warnings are turned off for this line only.
  Logfile << "The data is " << data_ << ".\n";
  endNoWarnOnReads();
}

Here, you don't want to hold the lock while writing to a file, and you
don't care about race conditions in the log.

The analysis already tracks calls to Lock() and Unlock() in order to
update the set of locks that are known to be held at each program
point.  (For those who are unfamiliar with the analysis, a lock is
normally a C++ expression, such as this->mu_, that refers to a
particular mutex).  In order to turn off checking for part of a
method, I've introduced the concept of a "universal lock".  If you
hold the universal lock, then all thread safety checks succeed without
any warnings, just as if you held the actual lock (which in this case
would be mu_).  The begin/endNoWarn() annotations can then be
implemented as functions that acquire and release the universal lock:

void beginNoWarnOnRead() SHARED_LOCK_FUNCTION("*") { }
void endNoWarnOnRead() UNLOCK_FUNCTION("*") { }

Note that the "*" is a special syntax which denotes the universal
lock.  A string constant can never refer to an actual mutex, so there
is no ambiguity; because of this, strings are also a good place to put
any future extensions to the language of lock expressions.  An
additional advantage of this approach is that I can reuse existing
attributes, rather than having to introduce new ones.

I've checked this extension into clang already, but can change it if
anybody objects and/or has a better idea.

  -DeLesley

-- 
DeLesley Hutchins | Software Engineer | delesley at google.com | 505-206-0315



More information about the cfe-dev mailing list