/Users/deen/code/yugabyte-db/src/yb/util/unique_lock.h
Line | Count | Source |
1 | | // Copyright (c) Yugabyte, Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
4 | | // in compliance with the License. You may obtain a copy of the License at |
5 | | // |
6 | | // http://www.apache.org/licenses/LICENSE-2.0 |
7 | | // |
8 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
9 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
10 | | // or implied. See the License for the specific language governing permissions and limitations |
11 | | // under the License. |
12 | | |
13 | | #ifndef YB_UTIL_UNIQUE_LOCK_H |
14 | | #define YB_UTIL_UNIQUE_LOCK_H |
15 | | |
16 | | #include <condition_variable> |
17 | | #include <mutex> |
18 | | |
19 | | #include "yb/gutil/thread_annotations.h" |
20 | | |
21 | | namespace yb { |
22 | | |
23 | | #if THREAD_ANNOTATIONS_ENABLED |
24 | | |
25 | | // ------------------------------------------------------------------------------------------------ |
26 | | // Thread annotations enabled, using a UniqueLock wrapper class around std::unique_lock. |
27 | | // ------------------------------------------------------------------------------------------------ |
28 | | |
29 | 1.38M | #define UNIQUE_LOCK(lock_name, mutex) ::yb::UniqueLock<decltype(mutex)> lock_name(mutex); |
30 | | |
31 | | // A wrapper unique_lock that supports thread annotations. |
32 | | template<typename Mutex> |
33 | | class SCOPED_CAPABILITY UniqueLock { |
34 | | public: |
35 | 1.39M | explicit UniqueLock(Mutex &mutex) ACQUIRE(mutex) : unique_lock_(mutex) {} _ZN2yb10UniqueLockINS_13percpu_rwlockEEC2ERS1_ Line | Count | Source | 35 | 117 | explicit UniqueLock(Mutex &mutex) ACQUIRE(mutex) : unique_lock_(mutex) {} |
_ZN2yb10UniqueLockINSt3__15mutexEEC2ERS2_ Line | Count | Source | 35 | 1.39M | explicit UniqueLock(Mutex &mutex) ACQUIRE(mutex) : unique_lock_(mutex) {} |
_ZN2yb10UniqueLockINSt3__118shared_timed_mutexEEC2ERS2_ Line | Count | Source | 35 | 12 | explicit UniqueLock(Mutex &mutex) ACQUIRE(mutex) : unique_lock_(mutex) {} |
|
36 | | |
37 | | explicit UniqueLock(Mutex &mutex, std::defer_lock_t defer) : unique_lock_(mutex, defer) {} |
38 | | |
39 | 1.38M | ~UniqueLock() RELEASE() = default; _ZN2yb10UniqueLockINS_13percpu_rwlockEED2Ev Line | Count | Source | 39 | 117 | ~UniqueLock() RELEASE() = default; |
_ZN2yb10UniqueLockINSt3__15mutexEED2Ev Line | Count | Source | 39 | 1.38M | ~UniqueLock() RELEASE() = default; |
_ZN2yb10UniqueLockINSt3__118shared_timed_mutexEED2Ev Line | Count | Source | 39 | 12 | ~UniqueLock() RELEASE() = default; |
|
40 | | |
41 | 337k | void unlock() RELEASE() { unique_lock_.unlock(); } _ZN2yb10UniqueLockINS_13percpu_rwlockEE6unlockEv Line | Count | Source | 41 | 115 | void unlock() RELEASE() { unique_lock_.unlock(); } |
_ZN2yb10UniqueLockINSt3__15mutexEE6unlockEv Line | Count | Source | 41 | 337k | void unlock() RELEASE() { unique_lock_.unlock(); } |
|
42 | 15.2k | void lock() ACQUIRE() { unique_lock_.lock(); } _ZN2yb10UniqueLockINS_13percpu_rwlockEE4lockEv Line | Count | Source | 42 | 115 | void lock() ACQUIRE() { unique_lock_.lock(); } |
_ZN2yb10UniqueLockINSt3__15mutexEE4lockEv Line | Count | Source | 42 | 15.1k | void lock() ACQUIRE() { unique_lock_.lock(); } |
|
43 | | |
44 | 1.22M | std::unique_lock<Mutex>& internal_unique_lock() { return unique_lock_; } |
45 | | |
46 | 97 | Mutex* mutex() RETURN_CAPABILITY(unique_lock_.mutex()) { return unique_lock_.mutex(); } |
47 | | |
48 | | private: |
49 | | std::unique_lock<Mutex> unique_lock_; |
50 | | }; |
51 | | |
52 | | template<typename Mutex> |
53 | | void WaitOnConditionVariable(std::condition_variable* cond_var, UniqueLock<Mutex>* lock) |
54 | 14.7k | REQUIRES(*lock) { |
55 | 14.7k | cond_var->wait(lock->internal_unique_lock()); |
56 | 14.7k | } |
57 | | |
58 | | template<typename Mutex, typename Functor> |
59 | | void WaitOnConditionVariable( |
60 | 97 | std::condition_variable* cond_var, UniqueLock<Mutex>* lock, Functor f) { |
61 | 97 | cond_var->wait(lock->internal_unique_lock(), f); |
62 | 97 | } |
63 | | |
64 | | template <class Mutex> |
65 | 1.21M | std::unique_lock<Mutex>& GetLockForCondition(UniqueLock<Mutex>* lock) { |
66 | 1.21M | return lock->internal_unique_lock(); |
67 | 1.21M | } |
68 | | |
69 | | #else |
70 | | |
71 | | // ------------------------------------------------------------------------------------------------ |
72 | | // Thread annotations disabled, no wrapper class needed. |
73 | | // ------------------------------------------------------------------------------------------------ |
74 | | |
75 | | template<class Mutex> |
76 | | using UniqueLock = std::unique_lock<Mutex>; |
77 | | |
78 | | #define UNIQUE_LOCK(lock_name, mutex) std::unique_lock<decltype(mutex)> lock_name(mutex); |
79 | | |
80 | | template<typename Mutex> |
81 | | void WaitOnConditionVariable(std::condition_variable* cond_var, UniqueLock<Mutex>* lock) { |
82 | | cond_var->wait(*lock); |
83 | | } |
84 | | |
85 | | template<typename Mutex, typename Functor> |
86 | | void WaitOnConditionVariable( |
87 | | std::condition_variable* cond_var, UniqueLock<Mutex>* lock, Functor f) { |
88 | | cond_var->wait(*lock, f); |
89 | | } |
90 | | |
91 | | template <class Mutex> |
92 | | std::unique_lock<Mutex>& GetLockForCondition(UniqueLock<Mutex>* lock) { |
93 | | return *lock; |
94 | | } |
95 | | |
96 | | #endif |
97 | | |
98 | | } // namespace yb |
99 | | |
100 | | #endif // YB_UTIL_UNIQUE_LOCK_H |