/ src / threadsafety.h
threadsafety.h
 1  // Copyright (c) 2009-2010 Satoshi Nakamoto
 2  // Copyright (c) 2009-present The Bitcoin Core developers
 3  // Distributed under the MIT software license, see the accompanying
 4  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 5  
 6  #ifndef BITCOIN_THREADSAFETY_H
 7  #define BITCOIN_THREADSAFETY_H
 8  
 9  #include <mutex>
10  
11  #ifdef __clang__
12  // TL;DR Add GUARDED_BY(mutex) to member variables. The others are
13  // rarely necessary. Ex: int nFoo GUARDED_BY(cs_foo);
14  //
15  // See https://clang.llvm.org/docs/ThreadSafetyAnalysis.html
16  // for documentation.  The clang compiler can do advanced static analysis
17  // of locking when given the -Wthread-safety option.
18  #define LOCKABLE __attribute__((capability("")))
19  #define SCOPED_LOCKABLE __attribute__((scoped_lockable))
20  #define GUARDED_BY(x) __attribute__((guarded_by(x)))
21  #define PT_GUARDED_BY(x) __attribute__((pt_guarded_by(x)))
22  #define ACQUIRED_AFTER(...) __attribute__((acquired_after(__VA_ARGS__)))
23  #define ACQUIRED_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__)))
24  #define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__((acquire_capability(__VA_ARGS__)))
25  #define SHARED_LOCK_FUNCTION(...) __attribute__((acquire_shared_capability(__VA_ARGS__)))
26  #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__((try_acquire_capability(__VA_ARGS__)))
27  #define SHARED_TRYLOCK_FUNCTION(...) __attribute__((try_acquire_shared_capability(__VA_ARGS__)))
28  #define UNLOCK_FUNCTION(...) __attribute__((release_capability(__VA_ARGS__)))
29  #define SHARED_UNLOCK_FUNCTION(...) __attribute__((release_shared_capability(__VA_ARGS__)))
30  #define LOCK_RETURNED(x) __attribute__((lock_returned(x)))
31  #define LOCKS_EXCLUDED(...) __attribute__((locks_excluded(__VA_ARGS__)))
32  #define EXCLUSIVE_LOCKS_REQUIRED(...) __attribute__((requires_capability(__VA_ARGS__)))
33  #define SHARED_LOCKS_REQUIRED(...) __attribute__((requires_shared_capability(__VA_ARGS__)))
34  #define NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
35  #define ASSERT_EXCLUSIVE_LOCK(...) __attribute__((assert_capability(__VA_ARGS__)))
36  #else
37  #define LOCKABLE
38  #define SCOPED_LOCKABLE
39  #define GUARDED_BY(x)
40  #define PT_GUARDED_BY(x)
41  #define ACQUIRED_AFTER(...)
42  #define ACQUIRED_BEFORE(...)
43  #define EXCLUSIVE_LOCK_FUNCTION(...)
44  #define SHARED_LOCK_FUNCTION(...)
45  #define EXCLUSIVE_TRYLOCK_FUNCTION(...)
46  #define SHARED_TRYLOCK_FUNCTION(...)
47  #define UNLOCK_FUNCTION(...)
48  #define SHARED_UNLOCK_FUNCTION(...)
49  #define LOCK_RETURNED(x)
50  #define LOCKS_EXCLUDED(...)
51  #define EXCLUSIVE_LOCKS_REQUIRED(...)
52  #define SHARED_LOCKS_REQUIRED(...)
53  #define NO_THREAD_SAFETY_ANALYSIS
54  #define ASSERT_EXCLUSIVE_LOCK(...)
55  #endif // __GNUC__
56  
57  // StdMutex provides an annotated version of std::mutex for us,
58  // and should only be used when sync.h Mutex/LOCK/etc are not usable.
59  class LOCKABLE StdMutex : public std::mutex
60  {
61  public:
62  #ifdef __clang__
63      //! For negative capabilities in the Clang Thread Safety Analysis.
64      //! A negative requirement uses the EXCLUSIVE_LOCKS_REQUIRED attribute, in conjunction
65      //! with the ! operator, to indicate that a mutex should not be held.
66      const StdMutex& operator!() const { return *this; }
67  #endif // __clang__
68  };
69  
70  // StdLockGuard provides an annotated version of std::lock_guard for us,
71  // and should only be used when sync.h Mutex/LOCK/etc are not usable.
72  class SCOPED_LOCKABLE StdLockGuard : public std::lock_guard<StdMutex>
73  {
74  public:
75      explicit StdLockGuard(StdMutex& cs) EXCLUSIVE_LOCK_FUNCTION(cs) : std::lock_guard<StdMutex>(cs) {}
76      ~StdLockGuard() UNLOCK_FUNCTION() = default;
77  };
78  
79  #endif // BITCOIN_THREADSAFETY_H