1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef THREAD_SAFETY_ANNOTATIONS_H 17 #define THREAD_SAFETY_ANNOTATIONS_H 18 19 // https://clang.llvm.org/docs/ThreadSafetyAnalysis.html 20 // Enable thread safety attributes only with clang. 21 // The attributes can be safely erased when compiling with other compilers. 22 #if defined(__clang__) && (!defined(SWIG)) 23 #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) 24 #else 25 #define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op 26 #endif 27 28 #define CAPABILITY(x) \ 29 THREAD_ANNOTATION_ATTRIBUTE__(capability(x)) 30 31 #define SCOPED_CAPABILITY \ 32 THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) 33 34 #define GUARDED_BY(x) \ 35 THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) 36 37 #define PT_GUARDED_BY(x) \ 38 THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) 39 40 #define ACQUIRED_BEFORE(...) \ 41 THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__)) 42 43 #define ACQUIRED_AFTER(...) \ 44 THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__)) 45 46 #define REQUIRES(...) \ 47 THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__)) 48 49 #define REQUIRES_SHARED(...) \ 50 THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__)) 51 52 #define ACQUIRE(...) \ 53 THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__)) 54 55 #define ACQUIRE_SHARED(...) \ 56 THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__)) 57 58 #define RELEASE(...) \ 59 THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__)) 60 61 #define RELEASE_SHARED(...) \ 62 THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__)) 63 64 #define RELEASE_GENERIC(...) \ 65 THREAD_ANNOTATION_ATTRIBUTE__(release_generic_capability(__VA_ARGS__)) 66 67 #define TRY_ACQUIRE(...) \ 68 THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__)) 69 70 #define TRY_ACQUIRE_SHARED(...) \ 71 THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__)) 72 73 #define EXCLUDES(...) \ 74 THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) 75 76 #define ASSERT_CAPABILITY(x) \ 77 THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x)) 78 79 #define ASSERT_SHARED_CAPABILITY(x) \ 80 THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x)) 81 82 #define RETURN_CAPABILITY(x) \ 83 THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) 84 85 #define NO_THREAD_SAFETY_ANALYSIS \ 86 THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) 87 88 namespace OHOS::Rosen { 89 class CAPABILITY("mutex") SingleThreadGuard {}; 90 91 // ONLY used for those accessed ONLY on scene session manager thread. 92 // If other looper threads(NOT ffrt or ipc), define a new one. 93 constexpr SingleThreadGuard SCENE_GUARD; 94 95 template <typename Guard> 96 struct SCOPED_CAPABILITY ScopedGuard final { ScopedGuardfinal97 explicit ScopedGuard(const Guard& guard) ACQUIRE(guard) {} RELEASEfinal98 ~ScopedGuard() RELEASE() {} 99 100 ScopedGuard(const ScopedGuard&) = delete; 101 ScopedGuard& operator=(const ScopedGuard&) = delete; 102 }; 103 104 } // namespace OHOS::Rosen 105 106 // Use this for lambdas. THREAD_SAFETY_GUARD is preferred. 107 #define LOCK_GUARD(guard) \ 108 ACQUIRE(guard) RELEASE(guard) 109 110 // Use this for expressions. THREAD_SAFETY_GUARD is preferred. 111 #define LOCK_GUARD_TWO(guard, expr) \ 112 (OHOS::Rosen::ScopedGuard(guard), expr) 113 114 // Use this when LOCK_GUARD_TWO/THREAD_SAFETY_GUARD works failed. 115 #define LOCK_GUARD_EXPR(guard, expr) \ 116 [&] { \ 117 OHOS::Rosen::ScopedGuard lock(guard); \ 118 return (expr); \ 119 }() 120 121 // Do not use this. 122 #define CREATE_THREAD_SAFETY_GUARD(opt1, opt2, guard, ...) guard 123 124 // Use THREAD_SAFETY_GUARD for common cases, including LOCK_GUARD and LOCK_GUARD_TWO. 125 #define THREAD_SAFETY_GUARD(...) \ 126 CREATE_THREAD_SAFETY_GUARD(__VA_ARGS__, LOCK_GUARD_TWO, LOCK_GUARD,)(__VA_ARGS__) 127 128 #endif // THREAD_SAFETY_ANNOTATIONS_H 129