Index: third_party/tcmalloc/chromium/src/base/dynamic_annotations.h |
=================================================================== |
--- third_party/tcmalloc/chromium/src/base/dynamic_annotations.h (revision 87277) |
+++ third_party/tcmalloc/chromium/src/base/dynamic_annotations.h (working copy) |
@@ -246,6 +246,12 @@ |
ANNOTATE_IGNORE_READS_END();\ |
}while(0)\ |
+ /* Enable (enable!=0) or disable (enable==0) race detection for all threads. |
+ This annotation could be useful if you want to skip expensive race analysis |
+ during some period of program execution, e.g. during initialization. */ |
+ #define ANNOTATE_ENABLE_RACE_DETECTION(enable) \ |
+ AnnotateEnableRaceDetection(__FILE__, __LINE__, enable) |
+ |
/* ------------------------------------------------------------- |
Annotations useful for debugging. */ |
@@ -358,11 +364,47 @@ |
#define ANNOTATE_IGNORE_WRITES_END() /* empty */ |
#define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */ |
#define ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */ |
+ #define ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */ |
#define ANNOTATE_NO_OP(arg) /* empty */ |
#define ANNOTATE_FLUSH_STATE() /* empty */ |
#endif /* DYNAMIC_ANNOTATIONS_ENABLED */ |
+/* Macro definitions for GCC attributes that allow static thread safety |
+ analysis to recognize and use some of the dynamic annotations as |
+ escape hatches. |
+ TODO(lcwu): remove the check for __SUPPORT_DYN_ANNOTATION__ once the |
+ default crosstool/GCC supports these GCC attributes. */ |
+ |
+#define ANNOTALYSIS_STATIC_INLINE |
+#define ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY ; |
+ |
+#if defined(__GNUC__) && defined(__SUPPORT_TS_ANNOTATION__) \ |
+ && (!defined(SWIG)) && defined(__SUPPORT_DYN_ANNOTATION__) |
+ |
+#if DYNAMIC_ANNOTATIONS_ENABLED == 0 |
+#define ANNOTALYSIS_ONLY 1 |
+#undef ANNOTALYSIS_STATIC_INLINE |
+#define ANNOTALYSIS_STATIC_INLINE static inline |
+#undef ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
+#define ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY { (void)file; (void)line; } |
+#endif |
+#define ANNOTALYSIS_IGNORE_READS_BEGIN __attribute__ ((ignore_reads_begin)) |
+#define ANNOTALYSIS_IGNORE_READS_END __attribute__ ((ignore_reads_end)) |
+#define ANNOTALYSIS_IGNORE_WRITES_BEGIN __attribute__ ((ignore_writes_begin)) |
+#define ANNOTALYSIS_IGNORE_WRITES_END __attribute__ ((ignore_writes_end)) |
+#define ANNOTALYSIS_UNPROTECTED_READ __attribute__ ((unprotected_read)) |
+ |
+#else |
+ |
+#define ANNOTALYSIS_IGNORE_READS_BEGIN |
+#define ANNOTALYSIS_IGNORE_READS_END |
+#define ANNOTALYSIS_IGNORE_WRITES_BEGIN |
+#define ANNOTALYSIS_IGNORE_WRITES_END |
+#define ANNOTALYSIS_UNPROTECTED_READ |
+ |
+#endif |
+ |
/* Use the macros above rather than using these functions directly. */ |
#ifdef __cplusplus |
extern "C" { |
@@ -424,10 +466,19 @@ |
const volatile void *arg); |
void AnnotateThreadName(const char *file, int line, |
const char *name); |
-void AnnotateIgnoreReadsBegin(const char *file, int line); |
-void AnnotateIgnoreReadsEnd(const char *file, int line); |
-void AnnotateIgnoreWritesBegin(const char *file, int line); |
-void AnnotateIgnoreWritesEnd(const char *file, int line); |
+ANNOTALYSIS_STATIC_INLINE |
+void AnnotateIgnoreReadsBegin(const char *file, int line) |
+ ANNOTALYSIS_IGNORE_READS_BEGIN ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
+ANNOTALYSIS_STATIC_INLINE |
+void AnnotateIgnoreReadsEnd(const char *file, int line) |
+ ANNOTALYSIS_IGNORE_READS_END ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
+ANNOTALYSIS_STATIC_INLINE |
+void AnnotateIgnoreWritesBegin(const char *file, int line) |
+ ANNOTALYSIS_IGNORE_WRITES_BEGIN ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
+ANNOTALYSIS_STATIC_INLINE |
+void AnnotateIgnoreWritesEnd(const char *file, int line) |
+ ANNOTALYSIS_IGNORE_WRITES_END ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
+void AnnotateEnableRaceDetection(const char *file, int line, int enable); |
void AnnotateNoOp(const char *file, int line, |
const volatile void *arg); |
void AnnotateFlushState(const char *file, int line); |
@@ -449,6 +500,19 @@ |
*/ |
int RunningOnValgrind(void); |
+/* ValgrindSlowdown returns: |
+ * 1.0, if (RunningOnValgrind() == 0) |
+ * 50.0, if (RunningOnValgrind() != 0 && getenv("VALGRIND_SLOWDOWN") == NULL) |
+ * atof(getenv("VALGRIND_SLOWDOWN")) otherwise |
+ This function can be used to scale timeout values: |
+ EXAMPLE: |
+ for (;;) { |
+ DoExpensiveBackgroundTask(); |
+ SleepForSeconds(5 * ValgrindSlowdown()); |
+ } |
+ */ |
+double ValgrindSlowdown(void); |
+ |
#ifdef __cplusplus |
} |
#endif |
@@ -464,7 +528,8 @@ |
one can use |
... = ANNOTATE_UNPROTECTED_READ(x); */ |
template <class T> |
- inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) { |
+ inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) |
+ ANNOTALYSIS_UNPROTECTED_READ { |
ANNOTATE_IGNORE_READS_BEGIN(); |
T res = x; |
ANNOTATE_IGNORE_READS_END(); |
@@ -490,4 +555,67 @@ |
#endif /* DYNAMIC_ANNOTATIONS_ENABLED */ |
+/* Annotalysis, a GCC based static analyzer, is able to understand and use |
+ some of the dynamic annotations defined in this file. However, dynamic |
+ annotations are usually disabled in the opt mode (to avoid additional |
+ runtime overheads) while Annotalysis only works in the opt mode. |
+ In order for Annotalysis to use these dynamic annotations when they |
+ are disabled, we re-define these annotations here. Note that unlike the |
+ original macro definitions above, these macros are expanded to calls to |
+ static inline functions so that the compiler will be able to remove the |
+ calls after the analysis. */ |
+ |
+#ifdef ANNOTALYSIS_ONLY |
+ |
+ #undef ANNOTALYSIS_ONLY |
+ |
+ /* Undefine and re-define the macros that the static analyzer understands. */ |
+ #undef ANNOTATE_IGNORE_READS_BEGIN |
+ #define ANNOTATE_IGNORE_READS_BEGIN() \ |
+ AnnotateIgnoreReadsBegin(__FILE__, __LINE__) |
+ |
+ #undef ANNOTATE_IGNORE_READS_END |
+ #define ANNOTATE_IGNORE_READS_END() \ |
+ AnnotateIgnoreReadsEnd(__FILE__, __LINE__) |
+ |
+ #undef ANNOTATE_IGNORE_WRITES_BEGIN |
+ #define ANNOTATE_IGNORE_WRITES_BEGIN() \ |
+ AnnotateIgnoreWritesBegin(__FILE__, __LINE__) |
+ |
+ #undef ANNOTATE_IGNORE_WRITES_END |
+ #define ANNOTATE_IGNORE_WRITES_END() \ |
+ AnnotateIgnoreWritesEnd(__FILE__, __LINE__) |
+ |
+ #undef ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN |
+ #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ |
+ do { \ |
+ ANNOTATE_IGNORE_READS_BEGIN(); \ |
+ ANNOTATE_IGNORE_WRITES_BEGIN(); \ |
+ }while(0) \ |
+ |
+ #undef ANNOTATE_IGNORE_READS_AND_WRITES_END |
+ #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ |
+ do { \ |
+ ANNOTATE_IGNORE_WRITES_END(); \ |
+ ANNOTATE_IGNORE_READS_END(); \ |
+ }while(0) \ |
+ |
+ #if defined(__cplusplus) |
+ #undef ANNOTATE_UNPROTECTED_READ |
+ template <class T> |
+ inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) |
+ __attribute__ ((unprotected_read)) { |
+ ANNOTATE_IGNORE_READS_BEGIN(); |
+ T res = x; |
+ ANNOTATE_IGNORE_READS_END(); |
+ return res; |
+ } |
+ #endif /* __cplusplus */ |
+ |
+#endif /* ANNOTALYSIS_ONLY */ |
+ |
+/* Undefine the macros intended only in this file. */ |
+#undef ANNOTALYSIS_STATIC_INLINE |
+#undef ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
+ |
#endif /* BASE_DYNAMIC_ANNOTATIONS_H_ */ |