• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <mutex>
19 
20 #if defined(__clang__)
21 #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
22 #else
23 #define THREAD_ANNOTATION_ATTRIBUTE__(x)  // no-op
24 #endif
25 
26 #define CAPABILITY(x) \
27       THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
28 #define SCOPED_CAPABILITY \
29       THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
30 #define SHARED_CAPABILITY(...) \
31       THREAD_ANNOTATION_ATTRIBUTE__(shared_capability(__VA_ARGS__))
32 #define GUARDED_BY(x) \
33       THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
34 #define PT_GUARDED_BY(x) \
35       THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
36 #define EXCLUSIVE_LOCKS_REQUIRED(...) \
37       THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__))
38 #define SHARED_LOCKS_REQUIRED(...) \
39       THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__))
40 #define ACQUIRED_BEFORE(...) \
41       THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
42 #define ACQUIRED_AFTER(...) \
43       THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
44 #define REQUIRES(...) \
45       THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
46 #define REQUIRES_SHARED(...) \
47       THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))
48 #define ACQUIRE(...) \
49       THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))
50 #define ACQUIRE_SHARED(...) \
51       THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))
52 #define RELEASE(...) \
53       THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))
54 #define RELEASE_SHARED(...) \
55       THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))
56 #define TRY_ACQUIRE(...) \
57       THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))
58 #define TRY_ACQUIRE_SHARED(...) \
59       THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))
60 #define EXCLUDES(...) \
61       THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
62 #define ASSERT_CAPABILITY(x) \
63       THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
64 #define ASSERT_SHARED_CAPABILITY(x) \
65       THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
66 #define RETURN_CAPABILITY(x) \
67       THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
68 #define EXCLUSIVE_LOCK_FUNCTION(...) \
69       THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
70 #define EXCLUSIVE_TRYLOCK_FUNCTION(...) \
71       THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
72 #define SHARED_LOCK_FUNCTION(...) \
73       THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__))
74 #define SHARED_TRYLOCK_FUNCTION(...) \
75       THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__))
76 #define UNLOCK_FUNCTION(...) \
77       THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
78 #define SCOPED_LOCKABLE \
79       THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
80 #define LOCK_RETURNED(x) \
81       THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
82 #define NO_THREAD_SAFETY_ANALYSIS \
83       THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
84 namespace android {
85 namespace base {
86 // A class to help thread safety analysis deal with std::unique_lock and condition_variable.
87 //
88 // Clang's thread safety analysis currently doesn't perform alias analysis, so movable types
89 // like std::unique_lock can't be marked with thread safety annotations. This helper allows
90 // for manual assertion of lock state in a scope.
91 //
92 // For example:
93 //
94 //   std::mutex mutex;
95 //   std::condition_variable cv;
96 //   std::vector<int> vec GUARDED_BY(mutex);
97 //
98 //   int pop() {
99 //     std::unique_lock lock(mutex);
100 //     ScopedLockAssertion lock_assertion(mutex);
101 //     cv.wait(lock, []() {
102 //       ScopedLockAssertion lock_assertion(mutex);
103 //       return !vec.empty();
104 //     });
105 //
106 //     int result = vec.back();
107 //     vec.pop_back();
108 //     return result;
109 //   }
110 class SCOPED_CAPABILITY ScopedLockAssertion {
111  public:
ScopedLockAssertion(std::mutex & mutex)112   ScopedLockAssertion(std::mutex& mutex) ACQUIRE(mutex) {}
RELEASE()113   ~ScopedLockAssertion() RELEASE() {}
114 };
115 }  // namespace base
116 }  // namespace android
117 
118