/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/include/llvm/Support/Mutex.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- llvm/Support/Mutex.h - Mutex Operating System Concept -----*- C++ -*-===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file declares the llvm::sys::Mutex class. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #ifndef LLVM_SUPPORT_MUTEX_H |
15 | | #define LLVM_SUPPORT_MUTEX_H |
16 | | |
17 | | #include "llvm/Support/Compiler.h" |
18 | | #include "llvm/Support/Threading.h" |
19 | | #include <cassert> |
20 | | |
21 | | namespace llvm |
22 | | { |
23 | | namespace sys |
24 | | { |
25 | | /// @brief Platform agnostic Mutex class. |
26 | | class MutexImpl |
27 | | { |
28 | | /// @name Constructors |
29 | | /// @{ |
30 | | public: |
31 | | |
32 | | /// Initializes the lock but doesn't acquire it. if \p recursive is set |
33 | | /// to false, the lock will not be recursive which makes it cheaper but |
34 | | /// also more likely to deadlock (same thread can't acquire more than |
35 | | /// once). |
36 | | /// @brief Default Constructor. |
37 | | explicit MutexImpl(bool recursive = true); |
38 | | |
39 | | /// Releases and removes the lock |
40 | | /// @brief Destructor |
41 | | ~MutexImpl(); |
42 | | |
43 | | /// @} |
44 | | /// @name Methods |
45 | | /// @{ |
46 | | public: |
47 | | |
48 | | /// Attempts to unconditionally acquire the lock. If the lock is held by |
49 | | /// another thread, this method will wait until it can acquire the lock. |
50 | | /// @returns false if any kind of error occurs, true otherwise. |
51 | | /// @brief Unconditionally acquire the lock. |
52 | | bool acquire(); |
53 | | |
54 | | /// Attempts to release the lock. If the lock is held by the current |
55 | | /// thread, the lock is released allowing other threads to acquire the |
56 | | /// lock. |
57 | | /// @returns false if any kind of error occurs, true otherwise. |
58 | | /// @brief Unconditionally release the lock. |
59 | | bool release(); |
60 | | |
61 | | /// Attempts to acquire the lock without blocking. If the lock is not |
62 | | /// available, this function returns false quickly (without blocking). If |
63 | | /// the lock is available, it is acquired. |
64 | | /// @returns false if any kind of error occurs or the lock is not |
65 | | /// available, true otherwise. |
66 | | /// @brief Try to acquire the lock. |
67 | | bool tryacquire(); |
68 | | |
69 | | //@} |
70 | | /// @name Platform Dependent Data |
71 | | /// @{ |
72 | | private: |
73 | | #if defined(LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0 |
74 | | void* data_; ///< We don't know what the data will be |
75 | | #endif |
76 | | |
77 | | /// @} |
78 | | /// @name Do Not Implement |
79 | | /// @{ |
80 | | private: |
81 | | MutexImpl(const MutexImpl &) = delete; |
82 | | void operator=(const MutexImpl &) = delete; |
83 | | /// @} |
84 | | }; |
85 | | |
86 | | |
87 | | /// SmartMutex - A mutex with a compile time constant parameter that |
88 | | /// indicates whether this mutex should become a no-op when we're not |
89 | | /// running in multithreaded mode. |
90 | | template<bool mt_only> |
91 | | class SmartMutex { |
92 | | MutexImpl impl; |
93 | | unsigned acquired; |
94 | | bool recursive; |
95 | | public: |
96 | | explicit SmartMutex(bool rec = true) : |
97 | 376k | impl(rec), acquired(0), recursive(rec) { } llvm::sys::SmartMutex<true>::SmartMutex(bool) Line | Count | Source | 97 | 173k | impl(rec), acquired(0), recursive(rec) { } |
llvm::sys::SmartMutex<false>::SmartMutex(bool) Line | Count | Source | 97 | 202k | impl(rec), acquired(0), recursive(rec) { } |
|
98 | | |
99 | 1.86M | bool lock() { |
100 | 1.86M | if (!mt_only || 1.86M llvm_is_multithreaded()583k ) { |
101 | 1.86M | return impl.acquire(); |
102 | 1.86M | } else { |
103 | 0 | // Single-threaded debugging code. This would be racy in |
104 | 0 | // multithreaded mode, but provides not sanity checks in single |
105 | 0 | // threaded mode. |
106 | 0 | assert((recursive || acquired == 0) && "Lock already acquired!!"); |
107 | 0 | ++acquired; |
108 | 0 | return true; |
109 | 0 | } |
110 | 1.86M | } llvm::sys::SmartMutex<false>::lock() Line | Count | Source | 99 | 1.28M | bool lock() { | 100 | 1.28M | if (!mt_only || 1.28M llvm_is_multithreaded()0 ) { | 101 | 1.28M | return impl.acquire(); | 102 | 1.28M | } else { | 103 | 0 | // Single-threaded debugging code. This would be racy in | 104 | 0 | // multithreaded mode, but provides not sanity checks in single | 105 | 0 | // threaded mode. | 106 | 0 | assert((recursive || acquired == 0) && "Lock already acquired!!"); | 107 | 0 | ++acquired; | 108 | 0 | return true; | 109 | 0 | } | 110 | 1.28M | } |
llvm::sys::SmartMutex<true>::lock() Line | Count | Source | 99 | 583k | bool lock() { | 100 | 583k | if (!mt_only || 583k llvm_is_multithreaded()583k ) { | 101 | 583k | return impl.acquire(); | 102 | 583k | } else { | 103 | 0 | // Single-threaded debugging code. This would be racy in | 104 | 0 | // multithreaded mode, but provides not sanity checks in single | 105 | 0 | // threaded mode. | 106 | 0 | assert((recursive || acquired == 0) && "Lock already acquired!!"); | 107 | 0 | ++acquired; | 108 | 0 | return true; | 109 | 0 | } | 110 | 583k | } |
|
111 | | |
112 | 1.86M | bool unlock() { |
113 | 1.86M | if (!mt_only || 1.86M llvm_is_multithreaded()583k ) { |
114 | 1.86M | return impl.release(); |
115 | 1.86M | } else { |
116 | 0 | // Single-threaded debugging code. This would be racy in |
117 | 0 | // multithreaded mode, but provides not sanity checks in single |
118 | 0 | // threaded mode. |
119 | 0 | assert(((recursive && acquired) || (acquired == 1)) && |
120 | 0 | "Lock not acquired before release!"); |
121 | 0 | --acquired; |
122 | 0 | return true; |
123 | 0 | } |
124 | 1.86M | } llvm::sys::SmartMutex<true>::unlock() Line | Count | Source | 112 | 583k | bool unlock() { | 113 | 583k | if (!mt_only || 583k llvm_is_multithreaded()583k ) { | 114 | 583k | return impl.release(); | 115 | 583k | } else { | 116 | 0 | // Single-threaded debugging code. This would be racy in | 117 | 0 | // multithreaded mode, but provides not sanity checks in single | 118 | 0 | // threaded mode. | 119 | 0 | assert(((recursive && acquired) || (acquired == 1)) && | 120 | 0 | "Lock not acquired before release!"); | 121 | 0 | --acquired; | 122 | 0 | return true; | 123 | 0 | } | 124 | 583k | } |
llvm::sys::SmartMutex<false>::unlock() Line | Count | Source | 112 | 1.28M | bool unlock() { | 113 | 1.28M | if (!mt_only || 1.28M llvm_is_multithreaded()0 ) { | 114 | 1.28M | return impl.release(); | 115 | 1.28M | } else { | 116 | 0 | // Single-threaded debugging code. This would be racy in | 117 | 0 | // multithreaded mode, but provides not sanity checks in single | 118 | 0 | // threaded mode. | 119 | 0 | assert(((recursive && acquired) || (acquired == 1)) && | 120 | 0 | "Lock not acquired before release!"); | 121 | 0 | --acquired; | 122 | 0 | return true; | 123 | 0 | } | 124 | 1.28M | } |
|
125 | | |
126 | | bool try_lock() { |
127 | | if (!mt_only || llvm_is_multithreaded()) |
128 | | return impl.tryacquire(); |
129 | | else return true; |
130 | | } |
131 | | |
132 | | private: |
133 | | SmartMutex(const SmartMutex<mt_only> & original); |
134 | | void operator=(const SmartMutex<mt_only> &); |
135 | | }; |
136 | | |
137 | | /// Mutex - A standard, always enforced mutex. |
138 | | typedef SmartMutex<false> Mutex; |
139 | | |
140 | | template<bool mt_only> |
141 | | class SmartScopedLock { |
142 | | SmartMutex<mt_only>& mtx; |
143 | | |
144 | | public: |
145 | 584k | SmartScopedLock(SmartMutex<mt_only>& m) : mtx(m) { |
146 | 584k | mtx.lock(); |
147 | 584k | } llvm::sys::SmartScopedLock<false>::SmartScopedLock(llvm::sys::SmartMutex<false>&) Line | Count | Source | 145 | 984 | SmartScopedLock(SmartMutex<mt_only>& m) : mtx(m) { | 146 | 984 | mtx.lock(); | 147 | 984 | } |
llvm::sys::SmartScopedLock<true>::SmartScopedLock(llvm::sys::SmartMutex<true>&) Line | Count | Source | 145 | 583k | SmartScopedLock(SmartMutex<mt_only>& m) : mtx(m) { | 146 | 583k | mtx.lock(); | 147 | 583k | } |
|
148 | | |
149 | 584k | ~SmartScopedLock() { |
150 | 584k | mtx.unlock(); |
151 | 584k | } llvm::sys::SmartScopedLock<false>::~SmartScopedLock() Line | Count | Source | 149 | 984 | ~SmartScopedLock() { | 150 | 984 | mtx.unlock(); | 151 | 984 | } |
llvm::sys::SmartScopedLock<true>::~SmartScopedLock() Line | Count | Source | 149 | 583k | ~SmartScopedLock() { | 150 | 583k | mtx.unlock(); | 151 | 583k | } |
|
152 | | }; |
153 | | |
154 | | typedef SmartScopedLock<false> ScopedLock; |
155 | | } |
156 | | } |
157 | | |
158 | | #endif |