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 88namespace OHOS::Rosen { 89class 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. 93constexpr SingleThreadGuard SCENE_GUARD; 94 95template <typename Guard> 96struct SCOPED_CAPABILITY ScopedGuard final { 97 explicit ScopedGuard(const Guard& guard) ACQUIRE(guard) {} 98 ~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