Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 1 | // Copyright 2017 The Abseil Authors. |
| 2 | // |
| 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 | // https://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. |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 14 | |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 15 | // This file defines dynamic annotations for use with dynamic analysis tool |
| 16 | // such as valgrind, PIN, etc. |
| 17 | // |
| 18 | // Dynamic annotation is a source code annotation that affects the generated |
| 19 | // code (that is, the annotation is not a comment). Each such annotation is |
| 20 | // attached to a particular instruction and/or to a particular object (address) |
| 21 | // in the program. |
| 22 | // |
| 23 | // The annotations that should be used by users are macros in all upper-case |
| 24 | // (e.g., ABSL_ANNOTATE_THREAD_NAME). |
| 25 | // |
| 26 | // Actual implementation of these macros may differ depending on the dynamic |
| 27 | // analysis tool being used. |
| 28 | // |
| 29 | // This file supports the following configurations: |
| 30 | // - Dynamic Annotations enabled (with static thread-safety warnings disabled). |
| 31 | // In this case, macros expand to functions implemented by Thread Sanitizer, |
| 32 | // when building with TSan. When not provided an external implementation, |
| 33 | // dynamic_annotations.cc provides no-op implementations. |
| 34 | // |
| 35 | // - Static Clang thread-safety warnings enabled. |
| 36 | // When building with a Clang compiler that supports thread-safety warnings, |
| 37 | // a subset of annotations can be statically-checked at compile-time. We |
| 38 | // expand these macros to static-inline functions that can be analyzed for |
| 39 | // thread-safety, but afterwards elided when building the final binary. |
| 40 | // |
| 41 | // - All annotations are disabled. |
| 42 | // If neither Dynamic Annotations nor Clang thread-safety warnings are |
| 43 | // enabled, then all annotation-macros expand to empty. |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 44 | |
| 45 | #ifndef ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ |
| 46 | #define ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ |
| 47 | |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 48 | #include <stddef.h> |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 49 | |
| 50 | #include "absl/base/attributes.h" |
| 51 | #include "absl/base/config.h" |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 52 | #ifdef __cplusplus |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 53 | #include "absl/base/macros.h" |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 54 | #endif |
| 55 | |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 56 | // TODO(rogeeff): Remove after the backward compatibility period. |
| 57 | #include "absl/base/internal/dynamic_annotations.h" // IWYU pragma: export |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 58 | |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 59 | // ------------------------------------------------------------------------- |
| 60 | // Decide which features are enabled. |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 61 | |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 62 | #ifdef ABSL_HAVE_THREAD_SANITIZER |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 63 | |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 64 | #define ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED 1 |
| 65 | #define ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED 1 |
| 66 | #define ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED 1 |
| 67 | #define ABSL_INTERNAL_ANNOTALYSIS_ENABLED 0 |
| 68 | #define ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED 1 |
| 69 | |
| 70 | #else |
| 71 | |
| 72 | #define ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED 0 |
| 73 | #define ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED 0 |
| 74 | #define ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED 0 |
| 75 | |
| 76 | // Clang provides limited support for static thread-safety analysis through a |
| 77 | // feature called Annotalysis. We configure macro-definitions according to |
| 78 | // whether Annotalysis support is available. When running in opt-mode, GCC |
| 79 | // will issue a warning, if these attributes are compiled. Only include them |
| 80 | // when compiling using Clang. |
| 81 | |
| 82 | #if defined(__clang__) |
| 83 | #define ABSL_INTERNAL_ANNOTALYSIS_ENABLED 1 |
| 84 | #if !defined(SWIG) |
| 85 | #define ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED 1 |
| 86 | #endif |
| 87 | #else |
| 88 | #define ABSL_INTERNAL_ANNOTALYSIS_ENABLED 0 |
| 89 | #endif |
| 90 | |
| 91 | // Read/write annotations are enabled in Annotalysis mode; disabled otherwise. |
| 92 | #define ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED \ |
| 93 | ABSL_INTERNAL_ANNOTALYSIS_ENABLED |
| 94 | |
| 95 | #endif // ABSL_HAVE_THREAD_SANITIZER |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 96 | |
| 97 | #ifdef __cplusplus |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 98 | #define ABSL_INTERNAL_BEGIN_EXTERN_C extern "C" { |
| 99 | #define ABSL_INTERNAL_END_EXTERN_C } // extern "C" |
| 100 | #define ABSL_INTERNAL_GLOBAL_SCOPED(F) ::F |
| 101 | #define ABSL_INTERNAL_STATIC_INLINE inline |
| 102 | #else |
| 103 | #define ABSL_INTERNAL_BEGIN_EXTERN_C // empty |
| 104 | #define ABSL_INTERNAL_END_EXTERN_C // empty |
| 105 | #define ABSL_INTERNAL_GLOBAL_SCOPED(F) F |
| 106 | #define ABSL_INTERNAL_STATIC_INLINE static inline |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 107 | #endif |
| 108 | |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 109 | // ------------------------------------------------------------------------- |
| 110 | // Define race annotations. |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 111 | |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 112 | #if ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 1 |
| 113 | |
| 114 | // ------------------------------------------------------------- |
| 115 | // Annotations that suppress errors. It is usually better to express the |
| 116 | // program's synchronization using the other annotations, but these can be used |
| 117 | // when all else fails. |
| 118 | |
| 119 | // Report that we may have a benign race at `pointer`, with size |
| 120 | // "sizeof(*(pointer))". `pointer` must be a non-void* pointer. Insert at the |
| 121 | // point where `pointer` has been allocated, preferably close to the point |
| 122 | // where the race happens. See also ABSL_ANNOTATE_BENIGN_RACE_STATIC. |
| 123 | #define ABSL_ANNOTATE_BENIGN_RACE(pointer, description) \ |
| 124 | ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateBenignRaceSized) \ |
| 125 | (__FILE__, __LINE__, pointer, sizeof(*(pointer)), description) |
| 126 | |
| 127 | // Same as ABSL_ANNOTATE_BENIGN_RACE(`address`, `description`), but applies to |
| 128 | // the memory range [`address`, `address`+`size`). |
| 129 | #define ABSL_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ |
| 130 | ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateBenignRaceSized) \ |
| 131 | (__FILE__, __LINE__, address, size, description) |
| 132 | |
| 133 | // Enable (`enable`!=0) or disable (`enable`==0) race detection for all threads. |
| 134 | // This annotation could be useful if you want to skip expensive race analysis |
| 135 | // during some period of program execution, e.g. during initialization. |
| 136 | #define ABSL_ANNOTATE_ENABLE_RACE_DETECTION(enable) \ |
| 137 | ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateEnableRaceDetection) \ |
| 138 | (__FILE__, __LINE__, enable) |
| 139 | |
| 140 | // ------------------------------------------------------------- |
| 141 | // Annotations useful for debugging. |
| 142 | |
| 143 | // Report the current thread `name` to a race detector. |
| 144 | #define ABSL_ANNOTATE_THREAD_NAME(name) \ |
| 145 | ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateThreadName)(__FILE__, __LINE__, name) |
| 146 | |
| 147 | // ------------------------------------------------------------- |
| 148 | // Annotations useful when implementing locks. They are not normally needed by |
| 149 | // modules that merely use locks. The `lock` argument is a pointer to the lock |
| 150 | // object. |
| 151 | |
| 152 | // Report that a lock has been created at address `lock`. |
| 153 | #define ABSL_ANNOTATE_RWLOCK_CREATE(lock) \ |
| 154 | ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockCreate)(__FILE__, __LINE__, lock) |
| 155 | |
| 156 | // Report that a linker initialized lock has been created at address `lock`. |
| 157 | #ifdef ABSL_HAVE_THREAD_SANITIZER |
| 158 | #define ABSL_ANNOTATE_RWLOCK_CREATE_STATIC(lock) \ |
| 159 | ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockCreateStatic) \ |
| 160 | (__FILE__, __LINE__, lock) |
| 161 | #else |
| 162 | #define ABSL_ANNOTATE_RWLOCK_CREATE_STATIC(lock) \ |
| 163 | ABSL_ANNOTATE_RWLOCK_CREATE(lock) |
| 164 | #endif |
| 165 | |
| 166 | // Report that the lock at address `lock` is about to be destroyed. |
| 167 | #define ABSL_ANNOTATE_RWLOCK_DESTROY(lock) \ |
| 168 | ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockDestroy)(__FILE__, __LINE__, lock) |
| 169 | |
| 170 | // Report that the lock at address `lock` has been acquired. |
| 171 | // `is_w`=1 for writer lock, `is_w`=0 for reader lock. |
| 172 | #define ABSL_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ |
| 173 | ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockAcquired) \ |
| 174 | (__FILE__, __LINE__, lock, is_w) |
| 175 | |
| 176 | // Report that the lock at address `lock` is about to be released. |
| 177 | // `is_w`=1 for writer lock, `is_w`=0 for reader lock. |
| 178 | #define ABSL_ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ |
| 179 | ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockReleased) \ |
| 180 | (__FILE__, __LINE__, lock, is_w) |
| 181 | |
| 182 | // Apply ABSL_ANNOTATE_BENIGN_RACE_SIZED to a static variable `static_var`. |
| 183 | #define ABSL_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ |
| 184 | namespace { \ |
| 185 | class static_var##_annotator { \ |
| 186 | public: \ |
| 187 | static_var##_annotator() { \ |
| 188 | ABSL_ANNOTATE_BENIGN_RACE_SIZED(&static_var, sizeof(static_var), \ |
| 189 | #static_var ": " description); \ |
| 190 | } \ |
| 191 | }; \ |
| 192 | static static_var##_annotator the##static_var##_annotator; \ |
| 193 | } // namespace |
| 194 | |
| 195 | // Function prototypes of annotations provided by the compiler-based sanitizer |
| 196 | // implementation. |
| 197 | ABSL_INTERNAL_BEGIN_EXTERN_C |
| 198 | void AnnotateRWLockCreate(const char* file, int line, |
| 199 | const volatile void* lock); |
| 200 | void AnnotateRWLockCreateStatic(const char* file, int line, |
| 201 | const volatile void* lock); |
| 202 | void AnnotateRWLockDestroy(const char* file, int line, |
| 203 | const volatile void* lock); |
| 204 | void AnnotateRWLockAcquired(const char* file, int line, |
| 205 | const volatile void* lock, long is_w); // NOLINT |
| 206 | void AnnotateRWLockReleased(const char* file, int line, |
| 207 | const volatile void* lock, long is_w); // NOLINT |
| 208 | void AnnotateBenignRace(const char* file, int line, |
| 209 | const volatile void* address, const char* description); |
| 210 | void AnnotateBenignRaceSized(const char* file, int line, |
| 211 | const volatile void* address, size_t size, |
| 212 | const char* description); |
| 213 | void AnnotateThreadName(const char* file, int line, const char* name); |
| 214 | void AnnotateEnableRaceDetection(const char* file, int line, int enable); |
| 215 | ABSL_INTERNAL_END_EXTERN_C |
| 216 | |
| 217 | #else // ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 0 |
| 218 | |
| 219 | #define ABSL_ANNOTATE_RWLOCK_CREATE(lock) // empty |
| 220 | #define ABSL_ANNOTATE_RWLOCK_CREATE_STATIC(lock) // empty |
| 221 | #define ABSL_ANNOTATE_RWLOCK_DESTROY(lock) // empty |
| 222 | #define ABSL_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) // empty |
| 223 | #define ABSL_ANNOTATE_RWLOCK_RELEASED(lock, is_w) // empty |
| 224 | #define ABSL_ANNOTATE_BENIGN_RACE(address, description) // empty |
| 225 | #define ABSL_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) // empty |
| 226 | #define ABSL_ANNOTATE_THREAD_NAME(name) // empty |
| 227 | #define ABSL_ANNOTATE_ENABLE_RACE_DETECTION(enable) // empty |
| 228 | #define ABSL_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) // empty |
| 229 | |
| 230 | #endif // ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED |
| 231 | |
| 232 | // ------------------------------------------------------------------------- |
| 233 | // Define memory annotations. |
| 234 | |
| 235 | #ifdef ABSL_HAVE_MEMORY_SANITIZER |
| 236 | |
| 237 | #include <sanitizer/msan_interface.h> |
| 238 | |
| 239 | #define ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ |
| 240 | __msan_unpoison(address, size) |
| 241 | |
| 242 | #define ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \ |
| 243 | __msan_allocated_memory(address, size) |
| 244 | |
| 245 | #else // !defined(ABSL_HAVE_MEMORY_SANITIZER) |
| 246 | |
| 247 | // TODO(rogeeff): remove this branch |
| 248 | #ifdef ABSL_HAVE_THREAD_SANITIZER |
| 249 | #define ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ |
| 250 | do { \ |
| 251 | (void)(address); \ |
| 252 | (void)(size); \ |
| 253 | } while (0) |
| 254 | #define ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \ |
| 255 | do { \ |
| 256 | (void)(address); \ |
| 257 | (void)(size); \ |
| 258 | } while (0) |
| 259 | #else |
| 260 | |
| 261 | #define ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) // empty |
| 262 | #define ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) // empty |
| 263 | |
| 264 | #endif |
| 265 | |
| 266 | #endif // ABSL_HAVE_MEMORY_SANITIZER |
| 267 | |
| 268 | // ------------------------------------------------------------------------- |
| 269 | // Define IGNORE_READS_BEGIN/_END attributes. |
| 270 | |
| 271 | #if defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED) |
| 272 | |
| 273 | #define ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE \ |
| 274 | __attribute((exclusive_lock_function("*"))) |
| 275 | #define ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE \ |
| 276 | __attribute((unlock_function("*"))) |
| 277 | |
| 278 | #else // !defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED) |
| 279 | |
| 280 | #define ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE // empty |
| 281 | #define ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE // empty |
| 282 | |
| 283 | #endif // defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED) |
| 284 | |
| 285 | // ------------------------------------------------------------------------- |
| 286 | // Define IGNORE_READS_BEGIN/_END annotations. |
| 287 | |
| 288 | #if ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED == 1 |
| 289 | |
| 290 | // Request the analysis tool to ignore all reads in the current thread until |
| 291 | // ABSL_ANNOTATE_IGNORE_READS_END is called. Useful to ignore intentional racey |
| 292 | // reads, while still checking other reads and all writes. |
| 293 | // See also ABSL_ANNOTATE_UNPROTECTED_READ. |
| 294 | #define ABSL_ANNOTATE_IGNORE_READS_BEGIN() \ |
| 295 | ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsBegin)(__FILE__, __LINE__) |
| 296 | |
| 297 | // Stop ignoring reads. |
| 298 | #define ABSL_ANNOTATE_IGNORE_READS_END() \ |
| 299 | ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsEnd)(__FILE__, __LINE__) |
| 300 | |
| 301 | // Function prototypes of annotations provided by the compiler-based sanitizer |
| 302 | // implementation. |
| 303 | ABSL_INTERNAL_BEGIN_EXTERN_C |
| 304 | void AnnotateIgnoreReadsBegin(const char* file, int line) |
| 305 | ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE; |
| 306 | void AnnotateIgnoreReadsEnd(const char* file, |
| 307 | int line) ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE; |
| 308 | ABSL_INTERNAL_END_EXTERN_C |
| 309 | |
| 310 | #elif defined(ABSL_INTERNAL_ANNOTALYSIS_ENABLED) |
| 311 | |
| 312 | // When Annotalysis is enabled without Dynamic Annotations, the use of |
| 313 | // static-inline functions allows the annotations to be read at compile-time, |
| 314 | // while still letting the compiler elide the functions from the final build. |
| 315 | // |
| 316 | // TODO(delesley) -- The exclusive lock here ignores writes as well, but |
| 317 | // allows IGNORE_READS_AND_WRITES to work properly. |
| 318 | |
| 319 | #define ABSL_ANNOTATE_IGNORE_READS_BEGIN() \ |
| 320 | ABSL_INTERNAL_GLOBAL_SCOPED(AbslInternalAnnotateIgnoreReadsBegin)() |
| 321 | |
| 322 | #define ABSL_ANNOTATE_IGNORE_READS_END() \ |
| 323 | ABSL_INTERNAL_GLOBAL_SCOPED(AbslInternalAnnotateIgnoreReadsEnd)() |
| 324 | |
| 325 | ABSL_INTERNAL_STATIC_INLINE void AbslInternalAnnotateIgnoreReadsBegin() |
| 326 | ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE {} |
| 327 | |
| 328 | ABSL_INTERNAL_STATIC_INLINE void AbslInternalAnnotateIgnoreReadsEnd() |
| 329 | ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE {} |
| 330 | |
| 331 | #else |
| 332 | |
| 333 | #define ABSL_ANNOTATE_IGNORE_READS_BEGIN() // empty |
| 334 | #define ABSL_ANNOTATE_IGNORE_READS_END() // empty |
| 335 | |
| 336 | #endif |
| 337 | |
| 338 | // ------------------------------------------------------------------------- |
| 339 | // Define IGNORE_WRITES_BEGIN/_END annotations. |
| 340 | |
| 341 | #if ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED == 1 |
| 342 | |
| 343 | // Similar to ABSL_ANNOTATE_IGNORE_READS_BEGIN, but ignore writes instead. |
| 344 | #define ABSL_ANNOTATE_IGNORE_WRITES_BEGIN() \ |
| 345 | ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreWritesBegin)(__FILE__, __LINE__) |
| 346 | |
| 347 | // Stop ignoring writes. |
| 348 | #define ABSL_ANNOTATE_IGNORE_WRITES_END() \ |
| 349 | ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreWritesEnd)(__FILE__, __LINE__) |
| 350 | |
| 351 | // Function prototypes of annotations provided by the compiler-based sanitizer |
| 352 | // implementation. |
| 353 | ABSL_INTERNAL_BEGIN_EXTERN_C |
| 354 | void AnnotateIgnoreWritesBegin(const char* file, int line); |
| 355 | void AnnotateIgnoreWritesEnd(const char* file, int line); |
| 356 | ABSL_INTERNAL_END_EXTERN_C |
| 357 | |
| 358 | #else |
| 359 | |
| 360 | #define ABSL_ANNOTATE_IGNORE_WRITES_BEGIN() // empty |
| 361 | #define ABSL_ANNOTATE_IGNORE_WRITES_END() // empty |
| 362 | |
| 363 | #endif |
| 364 | |
| 365 | // ------------------------------------------------------------------------- |
| 366 | // Define the ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_* annotations using the more |
| 367 | // primitive annotations defined above. |
| 368 | // |
| 369 | // Instead of doing |
| 370 | // ABSL_ANNOTATE_IGNORE_READS_BEGIN(); |
| 371 | // ... = x; |
| 372 | // ABSL_ANNOTATE_IGNORE_READS_END(); |
| 373 | // one can use |
| 374 | // ... = ABSL_ANNOTATE_UNPROTECTED_READ(x); |
| 375 | |
| 376 | #if defined(ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED) |
| 377 | |
| 378 | // Start ignoring all memory accesses (both reads and writes). |
| 379 | #define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ |
| 380 | do { \ |
| 381 | ABSL_ANNOTATE_IGNORE_READS_BEGIN(); \ |
| 382 | ABSL_ANNOTATE_IGNORE_WRITES_BEGIN(); \ |
| 383 | } while (0) |
| 384 | |
| 385 | // Stop ignoring both reads and writes. |
| 386 | #define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END() \ |
| 387 | do { \ |
| 388 | ABSL_ANNOTATE_IGNORE_WRITES_END(); \ |
| 389 | ABSL_ANNOTATE_IGNORE_READS_END(); \ |
| 390 | } while (0) |
| 391 | |
| 392 | #ifdef __cplusplus |
| 393 | // ABSL_ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. |
| 394 | #define ABSL_ANNOTATE_UNPROTECTED_READ(x) \ |
| 395 | absl::base_internal::AnnotateUnprotectedRead(x) |
| 396 | |
| 397 | namespace absl { |
| 398 | ABSL_NAMESPACE_BEGIN |
| 399 | namespace base_internal { |
| 400 | |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 401 | template <typename T> |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 402 | inline T AnnotateUnprotectedRead(const volatile T& x) { // NOLINT |
| 403 | ABSL_ANNOTATE_IGNORE_READS_BEGIN(); |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 404 | T res = x; |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 405 | ABSL_ANNOTATE_IGNORE_READS_END(); |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 406 | return res; |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 407 | } |
| 408 | |
| 409 | } // namespace base_internal |
| 410 | ABSL_NAMESPACE_END |
| 411 | } // namespace absl |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 412 | #endif |
| 413 | |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 414 | #else |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 415 | |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 416 | #define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() // empty |
| 417 | #define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END() // empty |
| 418 | #define ABSL_ANNOTATE_UNPROTECTED_READ(x) (x) |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 419 | |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 420 | #endif |
| 421 | |
| 422 | #ifdef __cplusplus |
| 423 | #ifdef ABSL_HAVE_THREAD_SANITIZER |
| 424 | ABSL_INTERNAL_BEGIN_EXTERN_C |
| 425 | int RunningOnValgrind(); |
| 426 | double ValgrindSlowdown(); |
| 427 | ABSL_INTERNAL_END_EXTERN_C |
| 428 | #else |
| 429 | namespace absl { |
| 430 | ABSL_NAMESPACE_BEGIN |
| 431 | namespace base_internal { |
| 432 | ABSL_DEPRECATED( |
| 433 | "Don't use this interface. It is misleading and is being deleted.") |
| 434 | ABSL_ATTRIBUTE_ALWAYS_INLINE inline int RunningOnValgrind() { return 0; } |
| 435 | ABSL_DEPRECATED( |
| 436 | "Don't use this interface. It is misleading and is being deleted.") |
| 437 | ABSL_ATTRIBUTE_ALWAYS_INLINE inline double ValgrindSlowdown() { return 1.0; } |
| 438 | } // namespace base_internal |
| 439 | ABSL_NAMESPACE_END |
| 440 | } // namespace absl |
| 441 | |
| 442 | using absl::base_internal::RunningOnValgrind; |
| 443 | using absl::base_internal::ValgrindSlowdown; |
| 444 | #endif |
| 445 | #endif |
| 446 | |
| 447 | // ------------------------------------------------------------------------- |
| 448 | // Address sanitizer annotations |
| 449 | |
| 450 | #ifdef ABSL_HAVE_ADDRESS_SANITIZER |
| 451 | // Describe the current state of a contiguous container such as e.g. |
| 452 | // std::vector or std::string. For more details see |
| 453 | // sanitizer/common_interface_defs.h, which is provided by the compiler. |
| 454 | #include <sanitizer/common_interface_defs.h> |
| 455 | |
| 456 | #define ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) \ |
| 457 | __sanitizer_annotate_contiguous_container(beg, end, old_mid, new_mid) |
| 458 | #define ABSL_ADDRESS_SANITIZER_REDZONE(name) \ |
| 459 | struct { \ |
| 460 | char x[8] __attribute__((aligned(8))); \ |
| 461 | } name |
| 462 | |
| 463 | #else |
| 464 | |
| 465 | #define ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) // empty |
| 466 | #define ABSL_ADDRESS_SANITIZER_REDZONE(name) static_assert(true, "") |
| 467 | |
| 468 | #endif // ABSL_HAVE_ADDRESS_SANITIZER |
| 469 | |
| 470 | // ------------------------------------------------------------------------- |
| 471 | // Undefine the macros intended only for this file. |
| 472 | |
| 473 | #undef ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED |
| 474 | #undef ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED |
| 475 | #undef ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED |
| 476 | #undef ABSL_INTERNAL_ANNOTALYSIS_ENABLED |
| 477 | #undef ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED |
| 478 | #undef ABSL_INTERNAL_BEGIN_EXTERN_C |
| 479 | #undef ABSL_INTERNAL_END_EXTERN_C |
| 480 | #undef ABSL_INTERNAL_STATIC_INLINE |
| 481 | |
| 482 | #endif // ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ |