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