/ src / threadsafety.h
threadsafety.h
 1  // Copyright (c) 2009-2010 Satoshi Nakamoto
 2  // Copyright (c) 2009-2020 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__((lockable))
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__((exclusive_lock_function(__VA_ARGS__)))
25  #define SHARED_LOCK_FUNCTION(...) __attribute__((shared_lock_function(__VA_ARGS__)))
26  #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__((exclusive_trylock_function(__VA_ARGS__)))
27  #define SHARED_TRYLOCK_FUNCTION(...) __attribute__((shared_trylock_function(__VA_ARGS__)))
28  #define UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__)))
29  #define LOCK_RETURNED(x) __attribute__((lock_returned(x)))
30  #define LOCKS_EXCLUDED(...) __attribute__((locks_excluded(__VA_ARGS__)))
31  #define EXCLUSIVE_LOCKS_REQUIRED(...) __attribute__((exclusive_locks_required(__VA_ARGS__)))
32  #define SHARED_LOCKS_REQUIRED(...) __attribute__((shared_locks_required(__VA_ARGS__)))
33  #define NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
34  #define ASSERT_EXCLUSIVE_LOCK(...) __attribute__((assert_exclusive_lock(__VA_ARGS__)))
35  #else
36  #define LOCKABLE
37  #define SCOPED_LOCKABLE
38  #define GUARDED_BY(x)
39  #define PT_GUARDED_BY(x)
40  #define ACQUIRED_AFTER(...)
41  #define ACQUIRED_BEFORE(...)
42  #define EXCLUSIVE_LOCK_FUNCTION(...)
43  #define SHARED_LOCK_FUNCTION(...)
44  #define EXCLUSIVE_TRYLOCK_FUNCTION(...)
45  #define SHARED_TRYLOCK_FUNCTION(...)
46  #define UNLOCK_FUNCTION(...)
47  #define LOCK_RETURNED(x)
48  #define LOCKS_EXCLUDED(...)
49  #define EXCLUSIVE_LOCKS_REQUIRED(...)
50  #define SHARED_LOCKS_REQUIRED(...)
51  #define NO_THREAD_SAFETY_ANALYSIS
52  #define ASSERT_EXCLUSIVE_LOCK(...)
53  #endif // __GNUC__
54  
55  // StdMutex provides an annotated version of std::mutex for us,
56  // and should only be used when sync.h Mutex/LOCK/etc are not usable.
57  class LOCKABLE StdMutex : public std::mutex
58  {
59  public:
60  #ifdef __clang__
61      //! For negative capabilities in the Clang Thread Safety Analysis.
62      //! A negative requirement uses the EXCLUSIVE_LOCKS_REQUIRED attribute, in conjunction
63      //! with the ! operator, to indicate that a mutex should not be held.
64      const StdMutex& operator!() const { return *this; }
65  #endif // __clang__
66  };
67  
68  // StdLockGuard provides an annotated version of std::lock_guard for us,
69  // and should only be used when sync.h Mutex/LOCK/etc are not usable.
70  class SCOPED_LOCKABLE StdLockGuard : public std::lock_guard<StdMutex>
71  {
72  public:
73      explicit StdLockGuard(StdMutex& cs) EXCLUSIVE_LOCK_FUNCTION(cs) : std::lock_guard<StdMutex>(cs) {}
74      ~StdLockGuard() UNLOCK_FUNCTION() {}
75  };
76  
77  #endif // BITCOIN_THREADSAFETY_H