1/*
2 * Copyright 2013-present Facebook, Inc.
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
17#include <folly/synchronization/SanitizeThread.h>
18
19// abseil uses size_t for size params while other FB code and libraries use
20// long, so it is helpful to keep these declarations out of widely-included
21// header files.
22
23extern "C" FOLLY_ATTR_WEAK void
24AnnotateRWLockCreate(const char* f, int l, const volatile void* addr);
25
26extern "C" FOLLY_ATTR_WEAK void
27AnnotateRWLockCreateStatic(const char* f, int l, const volatile void* addr);
28
29extern "C" FOLLY_ATTR_WEAK void
30AnnotateRWLockDestroy(const char* f, int l, const volatile void* addr);
31
32extern "C" FOLLY_ATTR_WEAK void
33AnnotateRWLockAcquired(const char* f, int l, const volatile void* addr, long w);
34
35extern "C" FOLLY_ATTR_WEAK void
36AnnotateRWLockReleased(const char* f, int l, const volatile void* addr, long w);
37
38extern "C" FOLLY_ATTR_WEAK void AnnotateBenignRaceSized(
39 const char* f,
40 int l,
41 const volatile void* addr,
42 long size,
43 const char* desc);
44
45namespace {
46void do_nothing(...) {}
47} // namespace
48
49#if _MSC_VER
50#define FOLLY_SANITIZE_THREAD_CALL_HOOK(name, ...) do_nothing(__VA_ARGS__)
51#else
52#define FOLLY_SANITIZE_THREAD_CALL_HOOK(name, ...) name(__VA_ARGS__)
53#endif
54
55namespace folly {
56namespace detail {
57
58void annotate_rwlock_create_impl(
59 void const volatile* const addr,
60 char const* const f,
61 int const l) {
62 if (kIsSanitizeThread) {
63 FOLLY_SANITIZE_THREAD_CALL_HOOK(AnnotateRWLockCreate, f, l, addr);
64 }
65}
66
67void annotate_rwlock_create_static_impl(
68 void const volatile* const addr,
69 char const* const f,
70 int const l) {
71 if (kIsSanitizeThread) {
72 FOLLY_SANITIZE_THREAD_CALL_HOOK(AnnotateRWLockCreateStatic, f, l, addr);
73 }
74}
75
76void annotate_rwlock_destroy_impl(
77 void const volatile* const addr,
78 char const* const f,
79 int const l) {
80 if (kIsSanitizeThread) {
81 FOLLY_SANITIZE_THREAD_CALL_HOOK(AnnotateRWLockDestroy, f, l, addr);
82 }
83}
84
85void annotate_rwlock_acquired_impl(
86 void const volatile* const addr,
87 annotate_rwlock_level const w,
88 char const* const f,
89 int const l) {
90 if (kIsSanitizeThread) {
91 FOLLY_SANITIZE_THREAD_CALL_HOOK(
92 AnnotateRWLockAcquired, f, l, addr, static_cast<long>(w));
93 }
94}
95
96void annotate_rwlock_try_acquired_impl(
97 void const volatile* const addr,
98 annotate_rwlock_level const w,
99 bool const result,
100 char const* const f,
101 int const l) {
102 if (result) {
103 annotate_rwlock_acquired(addr, w, f, l);
104 }
105}
106
107void annotate_rwlock_released_impl(
108 void const volatile* const addr,
109 annotate_rwlock_level const w,
110 char const* const f,
111 int const l) {
112 if (kIsSanitizeThread) {
113 FOLLY_SANITIZE_THREAD_CALL_HOOK(
114 AnnotateRWLockReleased, f, l, addr, static_cast<long>(w));
115 }
116}
117
118void annotate_benign_race_sized_impl(
119 const volatile void* addr,
120 long size,
121 const char* desc,
122 const char* f,
123 int l) {
124 if (kIsSanitizeThread) {
125 FOLLY_SANITIZE_THREAD_CALL_HOOK(
126 AnnotateBenignRaceSized, f, l, addr, size, desc);
127 }
128}
129} // namespace detail
130} // namespace folly
131