rcpputils  master
C++ API providing common utilities and data structures.
Macros | Functions
thread_safety_annotations.hpp File Reference

Enable thread safety attributes only with clang+libcxx. More...

#include <mutex>
Include dependency graph for thread_safety_annotations.hpp:

Go to the source code of this file.

Macros

#define RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(x)
 
#define RCPPUTILS_TSA_CAPABILITY(x)   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
 Attribute on classes, which specifies that objects of the class can be used as a capability. More...
 
#define RCPPUTILS_TSA_SCOPED_CAPABILITY   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
 Attribute on classes that implement RAII-style locking, in which a capability is acquired in the constructor, and released in the destructor. More...
 
#define RCPPUTILS_TSA_GUARDED_BY(x)   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
 Attribute on data members, which declares that the data member is protected by the given capability. More...
 
#define RCPPUTILS_TSA_PT_GUARDED_BY(x)   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
 Similar to RCPPUTILS_TSA_GUARDED_BY, but is intended for use on pointers and smart pointers. More...
 
#define RCPPUTILS_TSA_ACQUIRED_BEFORE(...)   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
 Attribute on member declarations, specifically declarations of mutexes or other capabilities. More...
 
#define RCPPUTILS_TSA_ACQUIRED_AFTER(...)   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
 Attribute on member declarations, specifically declarations of mutexes or other capabilities. More...
 
#define RCPPUTILS_TSA_REQUIRES(...)   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
 Attribute on functions or methods, which declares that the calling thread must have exclusive access to the given capabilities. More...
 
#define RCPPUTILS_TSA_REQUIRES_SHARED(...)   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))
 Attribute on functions or methods, which declares that the calling thread must have shared access to the given capabilities. More...
 
#define RCPPUTILS_TSA_ACQUIRE(...)   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))
 Attribute on functions or methods, which declares that the function acquires a capability, but does not release it. More...
 
#define RCPPUTILS_TSA_ACQUIRE_SHARED(...)   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))
 Attribute on functions or methods, which declares that the function acquires a shared capability, but does not release it. More...
 
#define RCPPUTILS_TSA_RELEASE(...)   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))
 Declare that the function releases the given capability. More...
 
#define RCPPUTILS_TSA_RELEASE_SHARED(...)   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))
 Declare that the function releases the given shared capability. More...
 
#define RCPPUTILS_TSA_TRY_ACQUIRE(...)   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))
 Attempts to RCPPUTILS_TSA_ACQUIRE, but its return value will indicate whether it succeeded or failed. More...
 
#define RCPPUTILS_TSA_TRY_ACQUIRE_SHARED(...)   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))
 Attempts to RCPPUTILS_TSA_ACQUIRE_SHARED, but its return value will indicate whether it succeeded or failed. More...
 
#define RCPPUTILS_TSA_EXCLUDES(...)   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
 attribute prevents deadlock, by making sure that a mutex is not held. More...
 
#define RCPPUTILS_TSA_ASSERT_CAPABILITY(...)   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(__VA_ARGS__))
 Perform a run-time test to see whether the calling thread holds the given capability. More...
 
#define RCPPUTILS_TSA_ASSERT_SHARED_CAPABILITY(...)   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(__VA_ARGS__))
 Perform a run-time test to see whether the calling thread holds the given shared capability. More...
 
#define RCPPUTILS_TSA_RETURN_CAPABILITY(x)   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
 Attribute on functions or methods, which declares that the function returns a reference to the given capability. More...
 
#define RCPPUTILS_TSA_NO_THREAD_SAFETY_ANALYSIS   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
 Attribute on functions or methods, which turns off thread safety checking for that method. More...
 

Functions

const std::mutexoperator! (const std::mutex &a)
 Defined for negation functionality. More...
 

Detailed Description

Enable thread safety attributes only with clang+libcxx.

Technically they would work with clang without libcxx, on manually-annotated thread safety primitives, but this use case causes the error of annotating against non-annotated libstdc++ types. Users that wish to annotate their threading library will need to define these macros separately for that case.

The attributes can be safely erased when compiling with other compilers.

Macro descriptions were obtained from llvm's thread safety annotation documentation, see their documentation for more info

Macro Definition Documentation

◆ RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__

#define RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__ (   x)

◆ RCPPUTILS_TSA_CAPABILITY

#define RCPPUTILS_TSA_CAPABILITY (   x)    RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(capability(x))

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 mutex.h at: https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#capability-string

◆ RCPPUTILS_TSA_SCOPED_CAPABILITY

#define RCPPUTILS_TSA_SCOPED_CAPABILITY   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)

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 mutex.h, at: https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#scoped-capability

◆ RCPPUTILS_TSA_GUARDED_BY

#define RCPPUTILS_TSA_GUARDED_BY (   x)    RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))

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. https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#guarded-by-c-and-pt-guarded-by-c

◆ RCPPUTILS_TSA_PT_GUARDED_BY

#define RCPPUTILS_TSA_PT_GUARDED_BY (   x)    RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))

Similar to RCPPUTILS_TSA_GUARDED_BY, 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. https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#guarded-by-c-and-pt-guarded-by-c

◆ RCPPUTILS_TSA_ACQUIRED_BEFORE

#define RCPPUTILS_TSA_ACQUIRED_BEFORE (   ...)    RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))

Attribute 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. https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#acquired-before-acquired-after

◆ RCPPUTILS_TSA_ACQUIRED_AFTER

#define RCPPUTILS_TSA_ACQUIRED_AFTER (   ...)    RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))

Attribute 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. https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#acquired-before-acquired-after

◆ RCPPUTILS_TSA_REQUIRES

#define RCPPUTILS_TSA_REQUIRES (   ...)    RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))

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. https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#requires-requires-shared

◆ RCPPUTILS_TSA_REQUIRES_SHARED

#define RCPPUTILS_TSA_REQUIRES_SHARED (   ...)    RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))

Attribute on functions or methods, which declares that the calling thread must have shared 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. https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#requires-requires-shared

◆ RCPPUTILS_TSA_ACQUIRE

#define RCPPUTILS_TSA_ACQUIRE (   ...)    RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))

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. https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#acquire-acquire-shared-release-release-shared

◆ RCPPUTILS_TSA_ACQUIRE_SHARED

#define RCPPUTILS_TSA_ACQUIRE_SHARED (   ...)    RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))

Attribute on functions or methods, which declares that the function acquires a shared capability, but does not release it.

The caller must not hold the given capability on entry, and it will hold the capability on exit. https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#acquire-acquire-shared-release-release-shared

◆ RCPPUTILS_TSA_RELEASE

#define RCPPUTILS_TSA_RELEASE (   ...)    RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))

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. https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#acquire-acquire-shared-release-release-shared

◆ RCPPUTILS_TSA_RELEASE_SHARED

#define RCPPUTILS_TSA_RELEASE_SHARED (   ...)    RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))

Declare that the function releases the given shared capability.

The caller must hold the shared capability on entry, and will no longer hold it on exit. It does not matter whether the given capability is shared or exclusive. https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#acquire-acquire-shared-release-release-shared

◆ RCPPUTILS_TSA_TRY_ACQUIRE

#define RCPPUTILS_TSA_TRY_ACQUIRE (   ...)    RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))

Attempts to RCPPUTILS_TSA_ACQUIRE, but its return value will indicate whether it succeeded or failed.

https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#try-acquire-bool-try-acquire-shared-bool

◆ RCPPUTILS_TSA_TRY_ACQUIRE_SHARED

#define RCPPUTILS_TSA_TRY_ACQUIRE_SHARED (   ...)    RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))

Attempts to RCPPUTILS_TSA_ACQUIRE_SHARED, but its return value will indicate whether it succeeded or failed.

https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#try-acquire-bool-try-acquire-shared-bool

◆ RCPPUTILS_TSA_EXCLUDES

#define RCPPUTILS_TSA_EXCLUDES (   ...)    RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))

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 RCPPUTILS_TSA_REQUIRES. In particular:

◆ RCPPUTILS_TSA_ASSERT_CAPABILITY

#define RCPPUTILS_TSA_ASSERT_CAPABILITY (   ...)    RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(__VA_ARGS__))

Perform 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 https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#assert-capability-and-assert-shared-capability

◆ RCPPUTILS_TSA_ASSERT_SHARED_CAPABILITY

#define RCPPUTILS_TSA_ASSERT_SHARED_CAPABILITY (   ...)    RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(__VA_ARGS__))

Perform a run-time test to see whether the calling thread holds the given shared capability.

The function is assumed to fail (no return) if the capability is not held. https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#assert-capability-and-assert-shared-capability

◆ RCPPUTILS_TSA_RETURN_CAPABILITY

#define RCPPUTILS_TSA_RETURN_CAPABILITY (   x)    RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))

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. https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#return-capability-c

◆ RCPPUTILS_TSA_NO_THREAD_SAFETY_ANALYSIS

#define RCPPUTILS_TSA_NO_THREAD_SAFETY_ANALYSIS   RCPPUTILS_THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)

Attribute on functions or methods, which turns off thread safety checking for that method.

RCPPUTILS_TSA_NO_THREAD_SAFETY_ANALYSIS 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 Known Limitations, below. https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#return-capability-c

Function Documentation

◆ operator!()

const std::mutex& operator! ( const std::mutex a)
inline

Defined for negation functionality.

libcxx does not define this operator, needed for negative capabilities TODO Here until someone has a better idea