1 | /* |
2 | * Copyright 2019 Google LLC |
3 | * |
4 | * Use of this source code is governed by a BSD-style license that can be |
5 | * found in the LICENSE file. |
6 | */ |
7 | |
8 | #ifndef SkThreadAnnotations_DEFINED |
9 | #define SkThreadAnnotations_DEFINED |
10 | |
11 | // The bulk of this code is cribbed from: |
12 | // http://clang.llvm.org/docs/ThreadSafetyAnalysis.html |
13 | |
14 | #if defined(__clang__) && (!defined(SWIG)) |
15 | #define SK_THREAD_ANNOTATION_ATTRIBUTE(x) __attribute__((x)) |
16 | #else |
17 | #define SK_THREAD_ANNOTATION_ATTRIBUTE(x) // no-op |
18 | #endif |
19 | |
20 | #define SK_CAPABILITY(x) \ |
21 | SK_THREAD_ANNOTATION_ATTRIBUTE(capability(x)) |
22 | |
23 | #define SK_SCOPED_CAPABILITY \ |
24 | SK_THREAD_ANNOTATION_ATTRIBUTE(scoped_lockable) |
25 | |
26 | #define SK_GUARDED_BY(x) \ |
27 | SK_THREAD_ANNOTATION_ATTRIBUTE(guarded_by(x)) |
28 | |
29 | #define SK_PT_GUARDED_BY(x) \ |
30 | SK_THREAD_ANNOTATION_ATTRIBUTE(pt_guarded_by(x)) |
31 | |
32 | #define SK_ACQUIRED_BEFORE(...) \ |
33 | SK_THREAD_ANNOTATION_ATTRIBUTE(acquired_before(__VA_ARGS__)) |
34 | |
35 | #define SK_ACQUIRED_AFTER(...) \ |
36 | SK_THREAD_ANNOTATION_ATTRIBUTE(acquired_after(__VA_ARGS__)) |
37 | |
38 | #define SK_REQUIRES(...) \ |
39 | SK_THREAD_ANNOTATION_ATTRIBUTE(requires_capability(__VA_ARGS__)) |
40 | |
41 | #define SK_REQUIRES_SHARED(...) \ |
42 | SK_THREAD_ANNOTATION_ATTRIBUTE(requires_shared_capability(__VA_ARGS__)) |
43 | |
44 | #define SK_ACQUIRE(...) \ |
45 | SK_THREAD_ANNOTATION_ATTRIBUTE(acquire_capability(__VA_ARGS__)) |
46 | |
47 | #define SK_ACQUIRE_SHARED(...) \ |
48 | SK_THREAD_ANNOTATION_ATTRIBUTE(acquire_shared_capability(__VA_ARGS__)) |
49 | |
50 | // Would be SK_RELEASE, but that is already in use as SK_DEBUG vs. SK_RELEASE. |
51 | #define SK_RELEASE_CAPABILITY(...) \ |
52 | SK_THREAD_ANNOTATION_ATTRIBUTE(release_capability(__VA_ARGS__)) |
53 | |
54 | // For symmetry with SK_RELEASE_CAPABILITY. |
55 | #define SK_RELEASE_SHARED_CAPABILITY(...) \ |
56 | SK_THREAD_ANNOTATION_ATTRIBUTE(release_shared_capability(__VA_ARGS__)) |
57 | |
58 | #define SK_TRY_ACQUIRE(...) \ |
59 | SK_THREAD_ANNOTATION_ATTRIBUTE(try_acquire_capability(__VA_ARGS__)) |
60 | |
61 | #define SK_TRY_ACQUIRE_SHARED(...) \ |
62 | SK_THREAD_ANNOTATION_ATTRIBUTE(try_acquire_shared_capability(__VA_ARGS__)) |
63 | |
64 | #define SK_EXCLUDES(...) \ |
65 | SK_THREAD_ANNOTATION_ATTRIBUTE(locks_excluded(__VA_ARGS__)) |
66 | |
67 | #define SK_ASSERT_CAPABILITY(x) \ |
68 | SK_THREAD_ANNOTATION_ATTRIBUTE(assert_capability(x)) |
69 | |
70 | #define SK_ASSERT_SHARED_CAPABILITY(x) \ |
71 | SK_THREAD_ANNOTATION_ATTRIBUTE(assert_shared_capability(x)) |
72 | |
73 | #define SK_RETURN_CAPABILITY(x) \ |
74 | SK_THREAD_ANNOTATION_ATTRIBUTE(lock_returned(x)) |
75 | |
76 | #define SK_NO_THREAD_SAFETY_ANALYSIS \ |
77 | SK_THREAD_ANNOTATION_ATTRIBUTE(no_thread_safety_analysis) |
78 | |
79 | #if defined(SK_BUILD_FOR_GOOGLE3) && !defined(SK_BUILD_FOR_WASM_IN_GOOGLE3) |
80 | extern "C" { |
81 | void __google_potentially_blocking_region_begin(void); |
82 | void __google_potentially_blocking_region_end (void); |
83 | } |
84 | #define SK_POTENTIALLY_BLOCKING_REGION_BEGIN __google_potentially_blocking_region_begin() |
85 | #define SK_POTENTIALLY_BLOCKING_REGION_END __google_potentially_blocking_region_end() |
86 | #else |
87 | #define SK_POTENTIALLY_BLOCKING_REGION_BEGIN |
88 | #define SK_POTENTIALLY_BLOCKING_REGION_END |
89 | #endif |
90 | |
91 | #endif // SkThreadAnnotations_DEFINED |
92 | |