OLD | NEW |
1 /* Copyright (c) 2008, Google Inc. | 1 /* Copyright (c) 2008, Google Inc. |
2 * All rights reserved. | 2 * All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 ANNOTATE_IGNORE_WRITES_BEGIN();\ | 239 ANNOTATE_IGNORE_WRITES_BEGIN();\ |
240 }while(0)\ | 240 }while(0)\ |
241 | 241 |
242 /* Stop ignoring all memory accesses. */ | 242 /* Stop ignoring all memory accesses. */ |
243 #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ | 243 #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ |
244 do {\ | 244 do {\ |
245 ANNOTATE_IGNORE_WRITES_END();\ | 245 ANNOTATE_IGNORE_WRITES_END();\ |
246 ANNOTATE_IGNORE_READS_END();\ | 246 ANNOTATE_IGNORE_READS_END();\ |
247 }while(0)\ | 247 }while(0)\ |
248 | 248 |
| 249 /* Enable (enable!=0) or disable (enable==0) race detection for all threads. |
| 250 This annotation could be useful if you want to skip expensive race analysis |
| 251 during some period of program execution, e.g. during initialization. */ |
| 252 #define ANNOTATE_ENABLE_RACE_DETECTION(enable) \ |
| 253 AnnotateEnableRaceDetection(__FILE__, __LINE__, enable) |
| 254 |
249 /* ------------------------------------------------------------- | 255 /* ------------------------------------------------------------- |
250 Annotations useful for debugging. */ | 256 Annotations useful for debugging. */ |
251 | 257 |
252 /* Request to trace every access to "address". */ | 258 /* Request to trace every access to "address". */ |
253 #define ANNOTATE_TRACE_MEMORY(address) \ | 259 #define ANNOTATE_TRACE_MEMORY(address) \ |
254 AnnotateTraceMemory(__FILE__, __LINE__, address) | 260 AnnotateTraceMemory(__FILE__, __LINE__, address) |
255 | 261 |
256 /* Report the current thread name to a race detector. */ | 262 /* Report the current thread name to a race detector. */ |
257 #define ANNOTATE_THREAD_NAME(name) \ | 263 #define ANNOTATE_THREAD_NAME(name) \ |
258 AnnotateThreadName(__FILE__, __LINE__, name) | 264 AnnotateThreadName(__FILE__, __LINE__, name) |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */ | 357 #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */ |
352 #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */ | 358 #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */ |
353 #define ANNOTATE_TRACE_MEMORY(arg) /* empty */ | 359 #define ANNOTATE_TRACE_MEMORY(arg) /* empty */ |
354 #define ANNOTATE_THREAD_NAME(name) /* empty */ | 360 #define ANNOTATE_THREAD_NAME(name) /* empty */ |
355 #define ANNOTATE_IGNORE_READS_BEGIN() /* empty */ | 361 #define ANNOTATE_IGNORE_READS_BEGIN() /* empty */ |
356 #define ANNOTATE_IGNORE_READS_END() /* empty */ | 362 #define ANNOTATE_IGNORE_READS_END() /* empty */ |
357 #define ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */ | 363 #define ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */ |
358 #define ANNOTATE_IGNORE_WRITES_END() /* empty */ | 364 #define ANNOTATE_IGNORE_WRITES_END() /* empty */ |
359 #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */ | 365 #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */ |
360 #define ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */ | 366 #define ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */ |
| 367 #define ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */ |
361 #define ANNOTATE_NO_OP(arg) /* empty */ | 368 #define ANNOTATE_NO_OP(arg) /* empty */ |
362 #define ANNOTATE_FLUSH_STATE() /* empty */ | 369 #define ANNOTATE_FLUSH_STATE() /* empty */ |
363 | 370 |
364 #endif /* DYNAMIC_ANNOTATIONS_ENABLED */ | 371 #endif /* DYNAMIC_ANNOTATIONS_ENABLED */ |
365 | 372 |
| 373 /* Macro definitions for GCC attributes that allow static thread safety |
| 374 analysis to recognize and use some of the dynamic annotations as |
| 375 escape hatches. |
| 376 TODO(lcwu): remove the check for __SUPPORT_DYN_ANNOTATION__ once the |
| 377 default crosstool/GCC supports these GCC attributes. */ |
| 378 |
| 379 #define ANNOTALYSIS_STATIC_INLINE |
| 380 #define ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY ; |
| 381 |
| 382 #if defined(__GNUC__) && defined(__SUPPORT_TS_ANNOTATION__) \ |
| 383 && (!defined(SWIG)) && defined(__SUPPORT_DYN_ANNOTATION__) |
| 384 |
| 385 #if DYNAMIC_ANNOTATIONS_ENABLED == 0 |
| 386 #define ANNOTALYSIS_ONLY 1 |
| 387 #undef ANNOTALYSIS_STATIC_INLINE |
| 388 #define ANNOTALYSIS_STATIC_INLINE static inline |
| 389 #undef ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
| 390 #define ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY { (void)file; (void)line; } |
| 391 #endif |
| 392 #define ANNOTALYSIS_IGNORE_READS_BEGIN __attribute__ ((ignore_reads_begin)) |
| 393 #define ANNOTALYSIS_IGNORE_READS_END __attribute__ ((ignore_reads_end)) |
| 394 #define ANNOTALYSIS_IGNORE_WRITES_BEGIN __attribute__ ((ignore_writes_begin)) |
| 395 #define ANNOTALYSIS_IGNORE_WRITES_END __attribute__ ((ignore_writes_end)) |
| 396 #define ANNOTALYSIS_UNPROTECTED_READ __attribute__ ((unprotected_read)) |
| 397 |
| 398 #else |
| 399 |
| 400 #define ANNOTALYSIS_IGNORE_READS_BEGIN |
| 401 #define ANNOTALYSIS_IGNORE_READS_END |
| 402 #define ANNOTALYSIS_IGNORE_WRITES_BEGIN |
| 403 #define ANNOTALYSIS_IGNORE_WRITES_END |
| 404 #define ANNOTALYSIS_UNPROTECTED_READ |
| 405 |
| 406 #endif |
| 407 |
366 /* Use the macros above rather than using these functions directly. */ | 408 /* Use the macros above rather than using these functions directly. */ |
367 #ifdef __cplusplus | 409 #ifdef __cplusplus |
368 extern "C" { | 410 extern "C" { |
369 #endif | 411 #endif |
370 void AnnotateRWLockCreate(const char *file, int line, | 412 void AnnotateRWLockCreate(const char *file, int line, |
371 const volatile void *lock); | 413 const volatile void *lock); |
372 void AnnotateRWLockDestroy(const char *file, int line, | 414 void AnnotateRWLockDestroy(const char *file, int line, |
373 const volatile void *lock); | 415 const volatile void *lock); |
374 void AnnotateRWLockAcquired(const char *file, int line, | 416 void AnnotateRWLockAcquired(const char *file, int line, |
375 const volatile void *lock, long is_w); | 417 const volatile void *lock, long is_w); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 void AnnotateBenignRaceSized(const char *file, int line, | 459 void AnnotateBenignRaceSized(const char *file, int line, |
418 const volatile void *address, | 460 const volatile void *address, |
419 long size, | 461 long size, |
420 const char *description); | 462 const char *description); |
421 void AnnotateMutexIsUsedAsCondVar(const char *file, int line, | 463 void AnnotateMutexIsUsedAsCondVar(const char *file, int line, |
422 const volatile void *mu); | 464 const volatile void *mu); |
423 void AnnotateTraceMemory(const char *file, int line, | 465 void AnnotateTraceMemory(const char *file, int line, |
424 const volatile void *arg); | 466 const volatile void *arg); |
425 void AnnotateThreadName(const char *file, int line, | 467 void AnnotateThreadName(const char *file, int line, |
426 const char *name); | 468 const char *name); |
427 void AnnotateIgnoreReadsBegin(const char *file, int line); | 469 ANNOTALYSIS_STATIC_INLINE |
428 void AnnotateIgnoreReadsEnd(const char *file, int line); | 470 void AnnotateIgnoreReadsBegin(const char *file, int line) |
429 void AnnotateIgnoreWritesBegin(const char *file, int line); | 471 ANNOTALYSIS_IGNORE_READS_BEGIN ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
430 void AnnotateIgnoreWritesEnd(const char *file, int line); | 472 ANNOTALYSIS_STATIC_INLINE |
| 473 void AnnotateIgnoreReadsEnd(const char *file, int line) |
| 474 ANNOTALYSIS_IGNORE_READS_END ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
| 475 ANNOTALYSIS_STATIC_INLINE |
| 476 void AnnotateIgnoreWritesBegin(const char *file, int line) |
| 477 ANNOTALYSIS_IGNORE_WRITES_BEGIN ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
| 478 ANNOTALYSIS_STATIC_INLINE |
| 479 void AnnotateIgnoreWritesEnd(const char *file, int line) |
| 480 ANNOTALYSIS_IGNORE_WRITES_END ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
| 481 void AnnotateEnableRaceDetection(const char *file, int line, int enable); |
431 void AnnotateNoOp(const char *file, int line, | 482 void AnnotateNoOp(const char *file, int line, |
432 const volatile void *arg); | 483 const volatile void *arg); |
433 void AnnotateFlushState(const char *file, int line); | 484 void AnnotateFlushState(const char *file, int line); |
434 | 485 |
435 /* Return non-zero value if running under valgrind. | 486 /* Return non-zero value if running under valgrind. |
436 | 487 |
437 If "valgrind.h" is included into dynamic_annotations.c, | 488 If "valgrind.h" is included into dynamic_annotations.c, |
438 the regular valgrind mechanism will be used. | 489 the regular valgrind mechanism will be used. |
439 See http://valgrind.org/docs/manual/manual-core-adv.html about | 490 See http://valgrind.org/docs/manual/manual-core-adv.html about |
440 RUNNING_ON_VALGRIND and other valgrind "client requests". | 491 RUNNING_ON_VALGRIND and other valgrind "client requests". |
441 The file "valgrind.h" may be obtained by doing | 492 The file "valgrind.h" may be obtained by doing |
442 svn co svn://svn.valgrind.org/valgrind/trunk/include | 493 svn co svn://svn.valgrind.org/valgrind/trunk/include |
443 | 494 |
444 If for some reason you can't use "valgrind.h" or want to fake valgrind, | 495 If for some reason you can't use "valgrind.h" or want to fake valgrind, |
445 there are two ways to make this function return non-zero: | 496 there are two ways to make this function return non-zero: |
446 - Use environment variable: export RUNNING_ON_VALGRIND=1 | 497 - Use environment variable: export RUNNING_ON_VALGRIND=1 |
447 - Make your tool intercept the function RunningOnValgrind() and | 498 - Make your tool intercept the function RunningOnValgrind() and |
448 change its return value. | 499 change its return value. |
449 */ | 500 */ |
450 int RunningOnValgrind(void); | 501 int RunningOnValgrind(void); |
451 | 502 |
| 503 /* ValgrindSlowdown returns: |
| 504 * 1.0, if (RunningOnValgrind() == 0) |
| 505 * 50.0, if (RunningOnValgrind() != 0 && getenv("VALGRIND_SLOWDOWN") == NULL) |
| 506 * atof(getenv("VALGRIND_SLOWDOWN")) otherwise |
| 507 This function can be used to scale timeout values: |
| 508 EXAMPLE: |
| 509 for (;;) { |
| 510 DoExpensiveBackgroundTask(); |
| 511 SleepForSeconds(5 * ValgrindSlowdown()); |
| 512 } |
| 513 */ |
| 514 double ValgrindSlowdown(void); |
| 515 |
452 #ifdef __cplusplus | 516 #ifdef __cplusplus |
453 } | 517 } |
454 #endif | 518 #endif |
455 | 519 |
456 #if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus) | 520 #if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus) |
457 | 521 |
458 /* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. | 522 /* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. |
459 | 523 |
460 Instead of doing | 524 Instead of doing |
461 ANNOTATE_IGNORE_READS_BEGIN(); | 525 ANNOTATE_IGNORE_READS_BEGIN(); |
462 ... = x; | 526 ... = x; |
463 ANNOTATE_IGNORE_READS_END(); | 527 ANNOTATE_IGNORE_READS_END(); |
464 one can use | 528 one can use |
465 ... = ANNOTATE_UNPROTECTED_READ(x); */ | 529 ... = ANNOTATE_UNPROTECTED_READ(x); */ |
466 template <class T> | 530 template <class T> |
467 inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) { | 531 inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) |
| 532 ANNOTALYSIS_UNPROTECTED_READ { |
468 ANNOTATE_IGNORE_READS_BEGIN(); | 533 ANNOTATE_IGNORE_READS_BEGIN(); |
469 T res = x; | 534 T res = x; |
470 ANNOTATE_IGNORE_READS_END(); | 535 ANNOTATE_IGNORE_READS_END(); |
471 return res; | 536 return res; |
472 } | 537 } |
473 /* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */ | 538 /* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */ |
474 #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ | 539 #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ |
475 namespace { \ | 540 namespace { \ |
476 class static_var ## _annotator { \ | 541 class static_var ## _annotator { \ |
477 public: \ | 542 public: \ |
478 static_var ## _annotator() { \ | 543 static_var ## _annotator() { \ |
479 ANNOTATE_BENIGN_RACE_SIZED(&static_var, \ | 544 ANNOTATE_BENIGN_RACE_SIZED(&static_var, \ |
480 sizeof(static_var), \ | 545 sizeof(static_var), \ |
481 # static_var ": " description); \ | 546 # static_var ": " description); \ |
482 } \ | 547 } \ |
483 }; \ | 548 }; \ |
484 static static_var ## _annotator the ## static_var ## _annotator;\ | 549 static static_var ## _annotator the ## static_var ## _annotator;\ |
485 } | 550 } |
486 #else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ | 551 #else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ |
487 | 552 |
488 #define ANNOTATE_UNPROTECTED_READ(x) (x) | 553 #define ANNOTATE_UNPROTECTED_READ(x) (x) |
489 #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */ | 554 #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */ |
490 | 555 |
491 #endif /* DYNAMIC_ANNOTATIONS_ENABLED */ | 556 #endif /* DYNAMIC_ANNOTATIONS_ENABLED */ |
492 | 557 |
| 558 /* Annotalysis, a GCC based static analyzer, is able to understand and use |
| 559 some of the dynamic annotations defined in this file. However, dynamic |
| 560 annotations are usually disabled in the opt mode (to avoid additional |
| 561 runtime overheads) while Annotalysis only works in the opt mode. |
| 562 In order for Annotalysis to use these dynamic annotations when they |
| 563 are disabled, we re-define these annotations here. Note that unlike the |
| 564 original macro definitions above, these macros are expanded to calls to |
| 565 static inline functions so that the compiler will be able to remove the |
| 566 calls after the analysis. */ |
| 567 |
| 568 #ifdef ANNOTALYSIS_ONLY |
| 569 |
| 570 #undef ANNOTALYSIS_ONLY |
| 571 |
| 572 /* Undefine and re-define the macros that the static analyzer understands. */ |
| 573 #undef ANNOTATE_IGNORE_READS_BEGIN |
| 574 #define ANNOTATE_IGNORE_READS_BEGIN() \ |
| 575 AnnotateIgnoreReadsBegin(__FILE__, __LINE__) |
| 576 |
| 577 #undef ANNOTATE_IGNORE_READS_END |
| 578 #define ANNOTATE_IGNORE_READS_END() \ |
| 579 AnnotateIgnoreReadsEnd(__FILE__, __LINE__) |
| 580 |
| 581 #undef ANNOTATE_IGNORE_WRITES_BEGIN |
| 582 #define ANNOTATE_IGNORE_WRITES_BEGIN() \ |
| 583 AnnotateIgnoreWritesBegin(__FILE__, __LINE__) |
| 584 |
| 585 #undef ANNOTATE_IGNORE_WRITES_END |
| 586 #define ANNOTATE_IGNORE_WRITES_END() \ |
| 587 AnnotateIgnoreWritesEnd(__FILE__, __LINE__) |
| 588 |
| 589 #undef ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN |
| 590 #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ |
| 591 do { \ |
| 592 ANNOTATE_IGNORE_READS_BEGIN(); \ |
| 593 ANNOTATE_IGNORE_WRITES_BEGIN(); \ |
| 594 }while(0) \ |
| 595 |
| 596 #undef ANNOTATE_IGNORE_READS_AND_WRITES_END |
| 597 #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ |
| 598 do { \ |
| 599 ANNOTATE_IGNORE_WRITES_END(); \ |
| 600 ANNOTATE_IGNORE_READS_END(); \ |
| 601 }while(0) \ |
| 602 |
| 603 #if defined(__cplusplus) |
| 604 #undef ANNOTATE_UNPROTECTED_READ |
| 605 template <class T> |
| 606 inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) |
| 607 __attribute__ ((unprotected_read)) { |
| 608 ANNOTATE_IGNORE_READS_BEGIN(); |
| 609 T res = x; |
| 610 ANNOTATE_IGNORE_READS_END(); |
| 611 return res; |
| 612 } |
| 613 #endif /* __cplusplus */ |
| 614 |
| 615 #endif /* ANNOTALYSIS_ONLY */ |
| 616 |
| 617 /* Undefine the macros intended only in this file. */ |
| 618 #undef ANNOTALYSIS_STATIC_INLINE |
| 619 #undef ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
| 620 |
493 #endif /* BASE_DYNAMIC_ANNOTATIONS_H_ */ | 621 #endif /* BASE_DYNAMIC_ANNOTATIONS_H_ */ |
OLD | NEW |