diff options
author | timurrrr@chromium.org <timurrrr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-14 08:24:42 +0000 |
---|---|---|
committer | timurrrr@chromium.org <timurrrr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-14 08:24:42 +0000 |
commit | ee857513c3a0d5c88bfd363c4203d4190fc678f5 (patch) | |
tree | 8e4ce0e72ced6eacd5711375f0a0d6bbe48c59a3 | |
parent | d4db59c55fdf97bf3abd60c58824fc090e0a7b61 (diff) | |
download | chromium_src-ee857513c3a0d5c88bfd363c4203d4190fc678f5.zip chromium_src-ee857513c3a0d5c88bfd363c4203d4190fc678f5.tar.gz chromium_src-ee857513c3a0d5c88bfd363c4203d4190fc678f5.tar.bz2 |
Update dynamic annotations and move them to base/third_party
Review URL: http://codereview.chromium.org/1992005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47252 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/allocator/allocator.gyp | 6 | ||||
-rw-r--r-- | base/atomic_ref_count.h | 2 | ||||
-rw-r--r-- | base/base.gypi | 39 | ||||
-rw-r--r-- | base/dynamic_annotations.cc | 67 | ||||
-rw-r--r-- | base/dynamic_annotations.h | 356 | ||||
-rw-r--r-- | base/lazy_instance.cc | 2 | ||||
-rw-r--r-- | base/lazy_instance.h | 2 | ||||
-rw-r--r-- | base/singleton.h | 2 | ||||
-rw-r--r-- | base/third_party/dynamic_annotations/LICENSE | 28 | ||||
-rw-r--r-- | base/third_party/dynamic_annotations/README.chromium | 11 | ||||
-rw-r--r-- | base/third_party/dynamic_annotations/dynamic_annotations.c | 159 | ||||
-rw-r--r-- | base/third_party/dynamic_annotations/dynamic_annotations.h | 511 | ||||
-rw-r--r-- | base/thread.cc | 2 | ||||
-rw-r--r-- | base/thread_unittest.cc | 2 | ||||
-rw-r--r-- | base/tools_sanity_unittest.cc | 2 | ||||
-rw-r--r-- | build/common.gypi | 5 | ||||
-rw-r--r-- | chrome/browser/geolocation/wifi_data_provider_common_unittest.cc | 2 | ||||
-rw-r--r-- | chrome/browser/sync/engine/syncer_thread.cc | 2 | ||||
-rw-r--r-- | chrome/browser/sync/glue/ui_model_worker.cc | 2 | ||||
-rw-r--r-- | ipc/ipc_sync_channel_unittest.cc | 2 | ||||
-rw-r--r-- | net/socket/tcp_pinger.h | 2 |
21 files changed, 767 insertions, 439 deletions
diff --git a/base/allocator/allocator.gyp b/base/allocator/allocator.gyp index a4a4edd..09ee3f9 100644 --- a/base/allocator/allocator.gyp +++ b/base/allocator/allocator.gyp @@ -57,7 +57,8 @@ '<(tcmalloc_dir)/src/base/basictypes.h', '<(tcmalloc_dir)/src/base/commandlineflags.h', '<(tcmalloc_dir)/src/base/cycleclock.h', - '<(tcmalloc_dir)/src/base/dynamic_annotations.cc', + # We don't list dynamic_annotations.cc since its copy is already + # present in the dynamic_annotations target. '<(tcmalloc_dir)/src/base/dynamic_annotations.h', '<(tcmalloc_dir)/src/base/elfcore.h', '<(tcmalloc_dir)/src/base/googleinit.h', @@ -242,6 +243,9 @@ '<(tcmalloc_dir)/src/windows/preamble_patcher.h', '<(tcmalloc_dir)/src/windows/preamble_patcher_with_stub.cc', ], + 'dependencies': [ + '../base.gyp:dynamic_annotations', + ], 'msvs_settings': { # TODO(sgk): merge this with build/common.gypi settings 'VCLibrarianTool=': { diff --git a/base/atomic_ref_count.h b/base/atomic_ref_count.h index 73d7f43..076a944 100644 --- a/base/atomic_ref_count.h +++ b/base/atomic_ref_count.h @@ -12,7 +12,7 @@ #define BASE_ATOMIC_REF_COUNT_H_ #include "base/atomicops.h" -#include "base/dynamic_annotations.h" +#include "base/third_party/dynamic_annotations/dynamic_annotations.h" namespace base { diff --git a/base/base.gypi b/base/base.gypi index ecec5cd..d529dab 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -64,8 +64,6 @@ 'dir_reader_fallback.h', 'dir_reader_linux.h', 'dir_reader_posix.h', - 'dynamic_annotations.h', - 'dynamic_annotations.cc', 'env_var.cc', 'env_var.h', 'event_trace_consumer_win.h', @@ -371,6 +369,7 @@ }, 'dependencies': [ '../third_party/modp_b64/modp_b64.gyp:modp_b64', + 'dynamic_annotations', ], # TODO(gregoryd): direct_dependent_settings should be shared with the # 64-bit target, but it doesn't work due to a bug in gyp @@ -573,17 +572,53 @@ 'version.h', ], }, + { + 'target_name': 'dynamic_annotations', + 'type': '<(library)', + 'msvs_guid': 'EF3AD1A1-5FA6-4B70-9CCC-F5AE4C6D0892', + 'include_dirs': [ + '..', + ], + 'sources': [ + 'third_party/dynamic_annotations/dynamic_annotations.c', + 'third_party/dynamic_annotations/dynamic_annotations.h', + ], + }, ], 'conditions': [ [ 'OS == "win"', { 'targets': [ { + 'target_name': 'dynamic_annotations_win64', + 'type': '<(library)', + 'msvs_guid': 'E8055455-0065-427B-9461-34A16FAD1973', + # We can't use dynamic_annotations target for win64 build since it is + # a 32-bit library. + # TODO(gregoryd): merge with dynamic_annotations when + # the win32/64 targets are merged. + 'include_dirs': [ + '..', + ], + 'sources': [ + 'third_party/dynamic_annotations/dynamic_annotations.c', + 'third_party/dynamic_annotations/dynamic_annotations.h', + ], + 'configurations': { + 'Common_Base': { + 'msvs_target_platform': 'x64', + }, + }, + }, + { 'target_name': 'base_nacl_win64', 'type': '<(library)', 'msvs_guid': 'CEE1F794-DC70-4FED-B7C4-4C12986672FE', 'variables': { 'base_target': 1, }, + 'dependencies': [ + 'dynamic_annotations_win64', + ], # TODO(gregoryd): direct_dependent_settings should be shared with the # 32-bit target, but it doesn't work due to a bug in gyp 'direct_dependent_settings': { diff --git a/base/dynamic_annotations.cc b/base/dynamic_annotations.cc deleted file mode 100644 index b1f4e19..0000000 --- a/base/dynamic_annotations.cc +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/dynamic_annotations.h" - -#ifndef NVALGRIND -// Each function is empty and called (via a macro) only in debug mode. -// The arguments are captured by dynamic tools at runtime. - -extern "C" void AnnotateRWLockCreate(const char *file, int line, - const volatile void *lock) {} -extern "C" void AnnotateRWLockDestroy(const char *file, int line, - const volatile void *lock) {} -extern "C" void AnnotateRWLockAcquired(const char *file, int line, - const volatile void *lock, long is_w) {} -extern "C" void AnnotateRWLockReleased(const char *file, int line, - const volatile void *lock, long is_w) {} -extern "C" void AnnotateCondVarWait(const char *file, int line, - const volatile void *cv, - const volatile void *lock) {} -extern "C" void AnnotateCondVarSignal(const char *file, int line, - const volatile void *cv) {} -extern "C" void AnnotateCondVarSignalAll(const char *file, int line, - const volatile void *cv) {} -extern "C" void AnnotatePublishMemoryRange(const char *file, int line, - const volatile void *address, - long size) {} -extern "C" void AnnotatePCQCreate(const char *file, int line, - const volatile void *pcq) {} -extern "C" void AnnotatePCQDestroy(const char *file, int line, - const volatile void *pcq) {} -extern "C" void AnnotatePCQPut(const char *file, int line, - const volatile void *pcq) {} -extern "C" void AnnotatePCQGet(const char *file, int line, - const volatile void *pcq) {} -extern "C" void AnnotateNewMemory(const char *file, int line, - const volatile void *mem, - long size) {} -extern "C" void AnnotateExpectRace(const char *file, int line, - const volatile void *mem, - const char *description) {} -extern "C" void AnnotateBenignRace(const char *file, int line, - const volatile void *mem, - const char *description) {} -extern "C" void AnnotateMutexIsUsedAsCondVar(const char *file, int line, - const volatile void *mu) {} -extern "C" void AnnotateTraceMemory(const char *file, int line, - const volatile void *arg) {} -extern "C" void AnnotateThreadName(const char *file, int line, - const char *name) {} -extern "C" void AnnotateIgnoreReadsBegin(const char *file, int line) {} -extern "C" void AnnotateIgnoreReadsEnd(const char *file, int line) {} -extern "C" void AnnotateIgnoreWritesBegin(const char *file, int line) {} -extern "C" void AnnotateIgnoreWritesEnd(const char *file, int line) {} -extern "C" void AnnotateNoOp(const char *file, int line, - const volatile void *arg) {} -#endif // NVALGRIND - -// When running under valgrind, a non-zero value will be returned. -extern "C" int RunningOnValgrind() { -#if defined(NVALGRIND) || !defined(RUNNING_ON_VALGRIND) - return 0; -#else - return RUNNING_ON_VALGRIND; -#endif -} diff --git a/base/dynamic_annotations.h b/base/dynamic_annotations.h deleted file mode 100644 index a6ed91e..0000000 --- a/base/dynamic_annotations.h +++ /dev/null @@ -1,356 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file defines dynamic annotations for use with dynamic analysis -// tool such as valgrind, PIN, etc. -// -// Dynamic annotation is a source code annotation that affects -// the generated code (that is, the annotation is not a comment). -// Each such annotation is attached to a particular -// instruction and/or to a particular object (address) in the program. -// -// The annotations that should be used by users are macros in all upper-case -// (e.g., ANNOTATE_NEW_MEMORY). -// -// Actual implementation of these macros may differ depending on the -// dynamic analysis tool being used. -// -// This file supports the following dynamic analysis tools: -// - None (NVALGRIND is defined). -// Macros are defined empty. -// - ThreadSanitizer (NVALGRIND is not defined). -// Macros are defined as calls to non-inlinable empty functions -// that are intercepted by ThreadSanitizer. -// -#ifndef BASE_DYNAMIC_ANNOTATIONS_H_ -#define BASE_DYNAMIC_ANNOTATIONS_H_ - -#ifdef __GNUC__ -// valgrind.h uses gcc extensions so it may not build with other compilers. -// Also, it defines NVALGRIND on Windows, which disables dynamic annotations -// for ThreadSanitizer. -#include "base/third_party/valgrind/valgrind.h" -#endif - -#ifndef NVALGRIND -// ------------------------------------------------------------- -// Annotations useful when implementing condition variables such as CondVar, -// using conditional critical sections (Await/LockWhen) and when constructing -// user-defined synchronization mechanisms. -// -// The annotations ANNOTATE_HAPPENS_BEFORE() and ANNOTATE_HAPPENS_AFTER() can -// be used to define happens-before arcs in user-defined synchronization -// mechanisms: the race detector will infer an arc from the former to the -// latter when they share the same argument pointer. -// -// Example 1 (reference counting): -// -// void Unref() { -// ANNOTATE_HAPPENS_BEFORE(&refcount_); -// if (AtomicDecrementByOne(&refcount_) == 0) { -// ANNOTATE_HAPPENS_AFTER(&refcount_); -// delete this; -// } -// } -// -// Example 2 (message queue): -// -// void MyQueue::Put(Type *e) { -// MutexLock lock(&mu_); -// ANNOTATE_HAPPENS_BEFORE(e); -// PutElementIntoMyQueue(e); -// } -// -// Type *MyQueue::Get() { -// MutexLock lock(&mu_); -// Type *e = GetElementFromMyQueue(); -// ANNOTATE_HAPPENS_AFTER(e); -// return e; -// } -// -// Note: when possible, please use the existing reference counting and message -// queue implementations instead of inventing new ones. - -// Report that wait on the condition variable at address "cv" has succeeded -// and the lock at address "lock" is held. -#define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \ - AnnotateCondVarWait(__FILE__, __LINE__, cv, lock) - -// Report that wait on the condition variable at "cv" has succeeded. Variant -// w/o lock. -#define ANNOTATE_CONDVAR_WAIT(cv) \ - AnnotateCondVarWait(__FILE__, __LINE__, cv, NULL) - -// Report that we are about to signal on the condition variable at address -// "cv". -#define ANNOTATE_CONDVAR_SIGNAL(cv) \ - AnnotateCondVarSignal(__FILE__, __LINE__, cv) - -// Report that we are about to signal_all on the condition variable at "cv". -#define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \ - AnnotateCondVarSignalAll(__FILE__, __LINE__, cv) - -// Annotations for user-defined synchronization mechanisms. -#define ANNOTATE_HAPPENS_BEFORE(obj) ANNOTATE_CONDVAR_SIGNAL(obj) -#define ANNOTATE_HAPPENS_AFTER(obj) ANNOTATE_CONDVAR_WAIT(obj) - -// Report that the bytes in the range [pointer, pointer+size) are about -// to be published safely. The race checker will create a happens-before -// arc from the call ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) to -// subsequent accesses to this memory. -#define ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \ - AnnotatePublishMemoryRange(__FILE__, __LINE__, pointer, size) - -// Instruct the tool to create a happens-before arc between mu->Unlock() and -// mu->Lock(). This annotation may slow down the race detector; normally it -// is used only when it would be difficult to annotate each of the mutex's -// critical sections individually using the annotations above. -#define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) \ - AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu) - -// ------------------------------------------------------------- -// Annotations useful when defining memory allocators, or when memory that -// was protected in one way starts to be protected in another. - -// Report that a new memory at "address" of size "size" has been allocated. -// This might be used when the memory has been retrieved from a free list and -// is about to be reused, or when a the locking discipline for a variable -// changes. -#define ANNOTATE_NEW_MEMORY(address, size) \ - AnnotateNewMemory(__FILE__, __LINE__, address, size) - -// ------------------------------------------------------------- -// Annotations useful when defining FIFO queues that transfer data between -// threads. - -// Report that the producer-consumer queue (such as ProducerConsumerQueue) at -// address "pcq" has been created. The ANNOTATE_PCQ_* annotations -// should be used only for FIFO queues. For non-FIFO queues use -// ANNOTATE_HAPPENS_BEFORE (for put) and ANNOTATE_HAPPENS_AFTER (for get). -#define ANNOTATE_PCQ_CREATE(pcq) \ - AnnotatePCQCreate(__FILE__, __LINE__, pcq) - -// Report that the queue at address "pcq" is about to be destroyed. -#define ANNOTATE_PCQ_DESTROY(pcq) \ - AnnotatePCQDestroy(__FILE__, __LINE__, pcq) - -// Report that we are about to put an element into a FIFO queue at address -// "pcq". -#define ANNOTATE_PCQ_PUT(pcq) \ - AnnotatePCQPut(__FILE__, __LINE__, pcq) - -// Report that we've just got an element from a FIFO queue at address "pcq". -#define ANNOTATE_PCQ_GET(pcq) \ - AnnotatePCQGet(__FILE__, __LINE__, pcq) - -// ------------------------------------------------------------- -// Annotations that suppress errors. It is usually better to express the -// program's synchronization using the other annotations, but these can -// be used when all else fails. - -// Report that we may have a benign race on at "address". -// Insert at the point where "address" has been allocated, preferably close -// to the point where the race happens. -// See also ANNOTATE_BENIGN_RACE_STATIC. -#define ANNOTATE_BENIGN_RACE(address, description) \ - AnnotateBenignRace(__FILE__, __LINE__, address, description) - -// Request the analysis tool to ignore all reads in the current thread -// until ANNOTATE_IGNORE_READS_END is called. -// Useful to ignore intentional racey reads, while still checking -// other reads and all writes. -// See also ANNOTATE_UNPROTECTED_READ. -#define ANNOTATE_IGNORE_READS_BEGIN() \ - AnnotateIgnoreReadsBegin(__FILE__, __LINE__) - -// Stop ignoring reads. -#define ANNOTATE_IGNORE_READS_END() \ - AnnotateIgnoreReadsEnd(__FILE__, __LINE__) - -// Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. -#define ANNOTATE_IGNORE_WRITES_BEGIN() \ - AnnotateIgnoreWritesBegin(__FILE__, __LINE__) - -// Stop ignoring writes. -#define ANNOTATE_IGNORE_WRITES_END() \ - AnnotateIgnoreWritesEnd(__FILE__, __LINE__) - -// Start ignoring all memory accesses (reads and writes). -#define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ - do {\ - ANNOTATE_IGNORE_READS_BEGIN();\ - ANNOTATE_IGNORE_WRITES_BEGIN();\ - }while(0)\ - -// Stop ignoring all memory accesses. -#define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ - do {\ - ANNOTATE_IGNORE_WRITES_END();\ - ANNOTATE_IGNORE_READS_END();\ - }while(0)\ - -// ------------------------------------------------------------- -// Annotations useful for debugging. - -// Request to trace every access to "address". -#define ANNOTATE_TRACE_MEMORY(address) \ - AnnotateTraceMemory(__FILE__, __LINE__, address) - -// Report the current thread name to a race detector. -#define ANNOTATE_THREAD_NAME(name) \ - AnnotateThreadName(__FILE__, __LINE__, name) - -// ------------------------------------------------------------- -// Annotations useful when implementing locks. They are not -// normally needed by modules that merely use locks. -// The "lock" argument is a pointer to the lock object. - -// Report that a lock has been created at address "lock". -#define ANNOTATE_RWLOCK_CREATE(lock) \ - AnnotateRWLockCreate(__FILE__, __LINE__, lock) - -// Report that the lock at address "lock" is about to be destroyed. -#define ANNOTATE_RWLOCK_DESTROY(lock) \ - AnnotateRWLockDestroy(__FILE__, __LINE__, lock) - -// Report that the lock at address "lock" has been acquired. -// is_w=1 for writer lock, is_w=0 for reader lock. -#define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ - AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w) - -// Report that the lock at address "lock" is about to be released. -#define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ - AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w) - -// ------------------------------------------------------------- -// Annotations useful for testing race detectors. - -// Report that we expect a race on the variable at "address". -// Use only in unit tests for a race detector. -#define ANNOTATE_EXPECT_RACE(address, description) \ - AnnotateExpectRace(__FILE__, __LINE__, address, description) - -// A no-op. Insert where you like to test the interceptors. -#define ANNOTATE_NO_OP(arg) \ - AnnotateNoOp(__FILE__, __LINE__, arg) - -// Use the macros above rather than using these functions directly. -extern "C" void AnnotateRWLockCreate(const char *file, int line, - const volatile void *lock); -extern "C" void AnnotateRWLockDestroy(const char *file, int line, - const volatile void *lock); -extern "C" void AnnotateRWLockAcquired(const char *file, int line, - const volatile void *lock, long is_w); -extern "C" void AnnotateRWLockReleased(const char *file, int line, - const volatile void *lock, long is_w); -extern "C" void AnnotateCondVarWait(const char *file, int line, - const volatile void *cv, - const volatile void *lock); -extern "C" void AnnotateCondVarSignal(const char *file, int line, - const volatile void *cv); -extern "C" void AnnotateCondVarSignalAll(const char *file, int line, - const volatile void *cv); -extern "C" void AnnotatePublishMemoryRange(const char *file, int line, - const volatile void *address, - long size); -extern "C" void AnnotatePCQCreate(const char *file, int line, - const volatile void *pcq); -extern "C" void AnnotatePCQDestroy(const char *file, int line, - const volatile void *pcq); -extern "C" void AnnotatePCQPut(const char *file, int line, - const volatile void *pcq); -extern "C" void AnnotatePCQGet(const char *file, int line, - const volatile void *pcq); -extern "C" void AnnotateNewMemory(const char *file, int line, - const volatile void *address, - long size); -extern "C" void AnnotateExpectRace(const char *file, int line, - const volatile void *address, - const char *description); -extern "C" void AnnotateBenignRace(const char *file, int line, - const volatile void *address, - const char *description); -extern "C" void AnnotateMutexIsUsedAsCondVar(const char *file, int line, - const volatile void *mu); -extern "C" void AnnotateTraceMemory(const char *file, int line, - const volatile void *arg); -extern "C" void AnnotateThreadName(const char *file, int line, - const char *name); -extern "C" void AnnotateIgnoreReadsBegin(const char *file, int line); -extern "C" void AnnotateIgnoreReadsEnd(const char *file, int line); -extern "C" void AnnotateIgnoreWritesBegin(const char *file, int line); -extern "C" void AnnotateIgnoreWritesEnd(const char *file, int line); -extern "C" void AnnotateNoOp(const char *file, int line, - const volatile void *arg); - -// ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. -// -// Instead of doing -// ANNOTATE_IGNORE_READS_BEGIN(); -// ... = x; -// ANNOTATE_IGNORE_READS_END(); -// one can use -// ... = ANNOTATE_UNPROTECTED_READ(x); -template <class T> -inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) { - ANNOTATE_IGNORE_READS_BEGIN(); - T res = x; - ANNOTATE_IGNORE_READS_END(); - return res; -} - -// Apply ANNOTATE_BENIGN_RACE to a static variable. -#define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ - namespace { \ - class static_var ## _annotator { \ - public: \ - static_var ## _annotator() { \ - ANNOTATE_BENIGN_RACE(&static_var, \ - # static_var ": " description); \ - } \ - }; \ - static static_var ## _annotator the ## static_var ## _annotator;\ - } - -#else -// NVALGRIND is defined, empty macros. - -#define ANNOTATE_RWLOCK_CREATE(lock) // empty -#define ANNOTATE_RWLOCK_DESTROY(lock) // empty -#define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) // empty -#define ANNOTATE_RWLOCK_RELEASED(lock, is_w) // empty -#define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) // empty -#define ANNOTATE_CONDVAR_WAIT(cv) // empty -#define ANNOTATE_CONDVAR_SIGNAL(cv) // empty -#define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) // empty -#define ANNOTATE_HAPPENS_BEFORE(obj) // empty -#define ANNOTATE_HAPPENS_AFTER(obj) // empty -#define ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) // empty -#define ANNOTATE_PUBLISH_OBJECT(address) // empty -#define ANNOTATE_PCQ_CREATE(pcq) // empty -#define ANNOTATE_PCQ_DESTROY(pcq) // empty -#define ANNOTATE_PCQ_PUT(pcq) // empty -#define ANNOTATE_PCQ_GET(pcq) // empty -#define ANNOTATE_NEW_MEMORY(address, size) // empty -#define ANNOTATE_EXPECT_RACE(address, description) // empty -#define ANNOTATE_BENIGN_RACE(address, description) // empty -#define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) // empty -#define ANNOTATE_TRACE_MEMORY(arg) // empty -#define ANNOTATE_THREAD_NAME(name) // empty -#define ANNOTATE_IGNORE_READS_BEGIN() // empty -#define ANNOTATE_IGNORE_READS_END() // empty -#define ANNOTATE_IGNORE_WRITES_BEGIN() // empty -#define ANNOTATE_IGNORE_WRITES_END() // empty -#define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() // empty -#define ANNOTATE_IGNORE_READS_AND_WRITES_END() // empty -#define ANNOTATE_NO_OP(arg) // empty -#define ANNOTATE_UNPROTECTED_READ(x) (x) -#define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) // empty - -#endif // NVALGRIND - -// Return non-zero value if running under valgrind. -extern "C" int RunningOnValgrind(); - -#endif // BASE_DYNAMIC_ANNOTATIONS_H_ diff --git a/base/lazy_instance.cc b/base/lazy_instance.cc index 565ad1f..f98ba3f 100644 --- a/base/lazy_instance.cc +++ b/base/lazy_instance.cc @@ -6,9 +6,9 @@ #include "base/at_exit.h" #include "base/atomicops.h" -#include "base/dynamic_annotations.h" #include "base/basictypes.h" #include "base/platform_thread.h" +#include "base/third_party/dynamic_annotations/dynamic_annotations.h" namespace base { diff --git a/base/lazy_instance.h b/base/lazy_instance.h index c6c170c..d639348 100644 --- a/base/lazy_instance.h +++ b/base/lazy_instance.h @@ -37,7 +37,7 @@ #include "base/atomicops.h" #include "base/basictypes.h" -#include "base/dynamic_annotations.h" +#include "base/third_party/dynamic_annotations/dynamic_annotations.h" namespace base { diff --git a/base/singleton.h b/base/singleton.h index 4532098..718834b 100644 --- a/base/singleton.h +++ b/base/singleton.h @@ -7,8 +7,8 @@ #include "base/at_exit.h" #include "base/atomicops.h" -#include "base/dynamic_annotations.h" #include "base/platform_thread.h" +#include "base/third_party/dynamic_annotations/dynamic_annotations.h" // Default traits for Singleton<Type>. Calls operator new and operator delete on // the object. Registers automatic deletion at process exit. diff --git a/base/third_party/dynamic_annotations/LICENSE b/base/third_party/dynamic_annotations/LICENSE new file mode 100644 index 0000000..5c581a9 --- /dev/null +++ b/base/third_party/dynamic_annotations/LICENSE @@ -0,0 +1,28 @@ +/* Copyright (c) 2008-2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * --- + * Author: Kostya Serebryany + */ diff --git a/base/third_party/dynamic_annotations/README.chromium b/base/third_party/dynamic_annotations/README.chromium new file mode 100644 index 0000000..f78a982 --- /dev/null +++ b/base/third_party/dynamic_annotations/README.chromium @@ -0,0 +1,11 @@ +Name: dynamic annotations +URL: http://code.google.com/p/data-race-test/wiki/DynamicAnnotations + +One header and one source file (dynamic_annotations.h and dynamic_annotations.c) +in this directory define runtime macros useful for annotating synchronization +utilities and benign data races so data race detectors can handle Chromium code +with better precision. + +These files were taken from +http://code.google.com/p/data-race-test/source/browse/?r=2062#svn/trunk/dynamic_annotations +The files are covered under BSD license as described within the files. diff --git a/base/third_party/dynamic_annotations/dynamic_annotations.c b/base/third_party/dynamic_annotations/dynamic_annotations.c new file mode 100644 index 0000000..5cfadb9 --- /dev/null +++ b/base/third_party/dynamic_annotations/dynamic_annotations.c @@ -0,0 +1,159 @@ +/* Copyright (c) 2008-2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * --- + * Author: Kostya Serebryany + */ + +#ifdef _MSC_VER +# include <windows.h> +#endif + +#ifdef __cplusplus +# error "This file should be built as pure C to avoid name mangling" +#endif + +#include <stdlib.h> +#include <string.h> + +#include "base/third_party/dynamic_annotations/dynamic_annotations.h" + +#ifdef __GNUC__ +/* valgrind.h uses gcc extensions so it won't build with other compilers */ +# include "base/third_party/valgrind/valgrind.h" +#endif + +/* Each function is empty and called (via a macro) only in debug mode. + The arguments are captured by dynamic tools at runtime. */ + +#if DYNAMIC_ANNOTATIONS_ENABLED == 1 + +void AnnotateRWLockCreate(const char *file, int line, + const volatile void *lock){} +void AnnotateRWLockDestroy(const char *file, int line, + const volatile void *lock){} +void AnnotateRWLockAcquired(const char *file, int line, + const volatile void *lock, long is_w){} +void AnnotateRWLockReleased(const char *file, int line, + const volatile void *lock, long is_w){} +void AnnotateBarrierInit(const char *file, int line, + const volatile void *barrier, long count, + long reinitialization_allowed) {} +void AnnotateBarrierWaitBefore(const char *file, int line, + const volatile void *barrier) {} +void AnnotateBarrierWaitAfter(const char *file, int line, + const volatile void *barrier) {} +void AnnotateBarrierDestroy(const char *file, int line, + const volatile void *barrier) {} + +void AnnotateCondVarWait(const char *file, int line, + const volatile void *cv, + const volatile void *lock){} +void AnnotateCondVarSignal(const char *file, int line, + const volatile void *cv){} +void AnnotateCondVarSignalAll(const char *file, int line, + const volatile void *cv){} +void AnnotatePublishMemoryRange(const char *file, int line, + const volatile void *address, + long size){} +void AnnotateUnpublishMemoryRange(const char *file, int line, + const volatile void *address, + long size){} +void AnnotatePCQCreate(const char *file, int line, + const volatile void *pcq){} +void AnnotatePCQDestroy(const char *file, int line, + const volatile void *pcq){} +void AnnotatePCQPut(const char *file, int line, + const volatile void *pcq){} +void AnnotatePCQGet(const char *file, int line, + const volatile void *pcq){} +void AnnotateNewMemory(const char *file, int line, + const volatile void *mem, + long size){} +void AnnotateExpectRace(const char *file, int line, + const volatile void *mem, + const char *description){} +void AnnotateBenignRace(const char *file, int line, + const volatile void *mem, + const char *description){} +void AnnotateBenignRaceSized(const char *file, int line, + const volatile void *mem, + long size, + const char *description) {} +void AnnotateMutexIsUsedAsCondVar(const char *file, int line, + const volatile void *mu){} +void AnnotateTraceMemory(const char *file, int line, + 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){} +void AnnotateIgnoreSyncBegin(const char *file, int line){} +void AnnotateIgnoreSyncEnd(const char *file, int line){} +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){} + +#endif /* DYNAMIC_ANNOTATIONS_ENABLED == 1 */ + +static int GetRunningOnValgrind(void) { +#ifdef RUNNING_ON_VALGRIND + if (RUNNING_ON_VALGRIND) return 1; +#endif + +#ifndef _MSC_VER + char *running_on_valgrind_str = getenv("RUNNING_ON_VALGRIND"); + if (running_on_valgrind_str) { + return strcmp(running_on_valgrind_str, "0") != 0; + } +#else + /* Visual Studio issues warnings if we use getenv, + * so we use GetEnvironmentVariableA instead. + */ + char value[100] = "1"; + int res = GetEnvironmentVariableA("RUNNING_ON_VALGRIND", + value, sizeof(value)); + /* value will remain "1" if res == 0 or res >= sizeof(value). The latter + * can happen only if the given value is long, in this case it can't be "0". + */ + if (res > 0 && !strcmp(value, "0")) + return 1; +#endif + return 0; +} + +/* See the comments in dynamic_annotations.h */ +int RunningOnValgrind(void) { + static volatile int running_on_valgrind = -1; + /* C doesn't have thread-safe initialization of statics, and we + don't want to depend on pthread_once here, so hack it. */ + int local_running_on_valgrind = running_on_valgrind; + if (local_running_on_valgrind == -1) + running_on_valgrind = local_running_on_valgrind = GetRunningOnValgrind(); + return local_running_on_valgrind; +} diff --git a/base/third_party/dynamic_annotations/dynamic_annotations.h b/base/third_party/dynamic_annotations/dynamic_annotations.h new file mode 100644 index 0000000..373f2ac --- /dev/null +++ b/base/third_party/dynamic_annotations/dynamic_annotations.h @@ -0,0 +1,511 @@ +/* Copyright (c) 2008-2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * --- + * Author: Kostya Serebryany + */ + +/* This file defines dynamic annotations for use with dynamic analysis + tool such as valgrind, PIN, etc. + + Dynamic annotation is a source code annotation that affects + the generated code (that is, the annotation is not a comment). + Each such annotation is attached to a particular + instruction and/or to a particular object (address) in the program. + + The annotations that should be used by users are macros in all upper-case + (e.g., ANNOTATE_NEW_MEMORY). + + Actual implementation of these macros may differ depending on the + dynamic analysis tool being used. + + See http://code.google.com/p/data-race-test/ for more information. + + This file supports the following dynamic analysis tools: + - None (DYNAMIC_ANNOTATIONS_ENABLED is not defined or zero). + Macros are defined empty. + - ThreadSanitizer, Helgrind, DRD (DYNAMIC_ANNOTATIONS_ENABLED is 1). + Macros are defined as calls to non-inlinable empty functions + that are intercepted by Valgrind. */ + +#ifndef __DYNAMIC_ANNOTATIONS_H__ +#define __DYNAMIC_ANNOTATIONS_H__ + +#ifndef DYNAMIC_ANNOTATIONS_ENABLED +# define DYNAMIC_ANNOTATIONS_ENABLED 0 +#endif + +#if DYNAMIC_ANNOTATIONS_ENABLED != 0 + + /* ------------------------------------------------------------- + Annotations useful when implementing condition variables such as CondVar, + using conditional critical sections (Await/LockWhen) and when constructing + user-defined synchronization mechanisms. + + The annotations ANNOTATE_HAPPENS_BEFORE() and ANNOTATE_HAPPENS_AFTER() can + be used to define happens-before arcs in user-defined synchronization + mechanisms: the race detector will infer an arc from the former to the + latter when they share the same argument pointer. + + Example 1 (reference counting): + + void Unref() { + ANNOTATE_HAPPENS_BEFORE(&refcount_); + if (AtomicDecrementByOne(&refcount_) == 0) { + ANNOTATE_HAPPENS_AFTER(&refcount_); + delete this; + } + } + + Example 2 (message queue): + + void MyQueue::Put(Type *e) { + MutexLock lock(&mu_); + ANNOTATE_HAPPENS_BEFORE(e); + PutElementIntoMyQueue(e); + } + + Type *MyQueue::Get() { + MutexLock lock(&mu_); + Type *e = GetElementFromMyQueue(); + ANNOTATE_HAPPENS_AFTER(e); + return e; + } + + Note: when possible, please use the existing reference counting and message + queue implementations instead of inventing new ones. */ + + /* Report that wait on the condition variable at address "cv" has succeeded + and the lock at address "lock" is held. */ + #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \ + AnnotateCondVarWait(__FILE__, __LINE__, cv, lock) + + /* Report that wait on the condition variable at "cv" has succeeded. Variant + w/o lock. */ + #define ANNOTATE_CONDVAR_WAIT(cv) \ + AnnotateCondVarWait(__FILE__, __LINE__, cv, NULL) + + /* Report that we are about to signal on the condition variable at address + "cv". */ + #define ANNOTATE_CONDVAR_SIGNAL(cv) \ + AnnotateCondVarSignal(__FILE__, __LINE__, cv) + + /* Report that we are about to signal_all on the condition variable at address + "cv". */ + #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \ + AnnotateCondVarSignalAll(__FILE__, __LINE__, cv) + + /* Annotations for user-defined synchronization mechanisms. */ + #define ANNOTATE_HAPPENS_BEFORE(obj) ANNOTATE_CONDVAR_SIGNAL(obj) + #define ANNOTATE_HAPPENS_AFTER(obj) ANNOTATE_CONDVAR_WAIT(obj) + + /* Report that the bytes in the range [pointer, pointer+size) are about + to be published safely. The race checker will create a happens-before + arc from the call ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) to + subsequent accesses to this memory. + Note: this annotation may not work properly if the race detector uses + sampling, i.e. does not observe all memory accesses. + */ + #define ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \ + AnnotatePublishMemoryRange(__FILE__, __LINE__, pointer, size) + + /* DEPRECATED. Don't use it. */ + #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size) \ + AnnotateUnpublishMemoryRange(__FILE__, __LINE__, pointer, size) + + /* DEPRECATED. Don't use it. */ + #define ANNOTATE_SWAP_MEMORY_RANGE(pointer, size) \ + do { \ + ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size); \ + ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size); \ + } while (0) + + /* Instruct the tool to create a happens-before arc between mu->Unlock() and + mu->Lock(). This annotation may slow down the race detector and hide real + races. Normally it is used only when it would be difficult to annotate each + of the mutex's critical sections individually using the annotations above. + This annotation makes sense only for hybrid race detectors. For pure + happens-before detectors this is a no-op. For more details see + http://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */ + #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) \ + AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu) + + /* Deprecated. Use ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX. */ + #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) \ + AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu) + + /* ------------------------------------------------------------- + Annotations useful when defining memory allocators, or when memory that + was protected in one way starts to be protected in another. */ + + /* Report that a new memory at "address" of size "size" has been allocated. + This might be used when the memory has been retrieved from a free list and + is about to be reused, or when a the locking discipline for a variable + changes. */ + #define ANNOTATE_NEW_MEMORY(address, size) \ + AnnotateNewMemory(__FILE__, __LINE__, address, size) + + /* ------------------------------------------------------------- + Annotations useful when defining FIFO queues that transfer data between + threads. */ + + /* Report that the producer-consumer queue (such as ProducerConsumerQueue) at + address "pcq" has been created. The ANNOTATE_PCQ_* annotations + should be used only for FIFO queues. For non-FIFO queues use + ANNOTATE_HAPPENS_BEFORE (for put) and ANNOTATE_HAPPENS_AFTER (for get). */ + #define ANNOTATE_PCQ_CREATE(pcq) \ + AnnotatePCQCreate(__FILE__, __LINE__, pcq) + + /* Report that the queue at address "pcq" is about to be destroyed. */ + #define ANNOTATE_PCQ_DESTROY(pcq) \ + AnnotatePCQDestroy(__FILE__, __LINE__, pcq) + + /* Report that we are about to put an element into a FIFO queue at address + "pcq". */ + #define ANNOTATE_PCQ_PUT(pcq) \ + AnnotatePCQPut(__FILE__, __LINE__, pcq) + + /* Report that we've just got an element from a FIFO queue at address + "pcq". */ + #define ANNOTATE_PCQ_GET(pcq) \ + AnnotatePCQGet(__FILE__, __LINE__, pcq) + + /* ------------------------------------------------------------- + Annotations that suppress errors. It is usually better to express the + program's synchronization using the other annotations, but these can + be used when all else fails. */ + + /* Report that we may have a benign race at "pointer", with size + "sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the + point where "pointer" has been allocated, preferably close to the point + where the race happens. See also ANNOTATE_BENIGN_RACE_STATIC. */ + #define ANNOTATE_BENIGN_RACE(pointer, description) \ + AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \ + sizeof(*(pointer)), description) + + /* Same as ANNOTATE_BENIGN_RACE(address, description), but applies to + the memory range [address, address+size). */ + #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ + AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description) + + /* Request the analysis tool to ignore all reads in the current thread + until ANNOTATE_IGNORE_READS_END is called. + Useful to ignore intentional racey reads, while still checking + other reads and all writes. + See also ANNOTATE_UNPROTECTED_READ. */ + #define ANNOTATE_IGNORE_READS_BEGIN() \ + AnnotateIgnoreReadsBegin(__FILE__, __LINE__) + + /* Stop ignoring reads. */ + #define ANNOTATE_IGNORE_READS_END() \ + AnnotateIgnoreReadsEnd(__FILE__, __LINE__) + + /* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. */ + #define ANNOTATE_IGNORE_WRITES_BEGIN() \ + AnnotateIgnoreWritesBegin(__FILE__, __LINE__) + + /* Stop ignoring writes. */ + #define ANNOTATE_IGNORE_WRITES_END() \ + AnnotateIgnoreWritesEnd(__FILE__, __LINE__) + + /* Start ignoring all memory accesses (reads and writes). */ + #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ + do {\ + ANNOTATE_IGNORE_READS_BEGIN();\ + ANNOTATE_IGNORE_WRITES_BEGIN();\ + }while(0)\ + + /* Stop ignoring all memory accesses. */ + #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ + do {\ + ANNOTATE_IGNORE_WRITES_END();\ + ANNOTATE_IGNORE_READS_END();\ + }while(0)\ + + /* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore synchronization events: + RWLOCK* and CONDVAR*. */ + #define ANNOTATE_IGNORE_SYNC_BEGIN() \ + AnnotateIgnoreSyncBegin(__FILE__, __LINE__) + + /* Stop ignoring sync events. */ + #define ANNOTATE_IGNORE_SYNC_END() \ + AnnotateIgnoreSyncEnd(__FILE__, __LINE__) + + + /* 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. */ + + /* Request to trace every access to "address". */ + #define ANNOTATE_TRACE_MEMORY(address) \ + AnnotateTraceMemory(__FILE__, __LINE__, address) + + /* Report the current thread name to a race detector. */ + #define ANNOTATE_THREAD_NAME(name) \ + AnnotateThreadName(__FILE__, __LINE__, name) + + /* ------------------------------------------------------------- + Annotations useful when implementing locks. They are not + normally needed by modules that merely use locks. + The "lock" argument is a pointer to the lock object. */ + + /* Report that a lock has been created at address "lock". */ + #define ANNOTATE_RWLOCK_CREATE(lock) \ + AnnotateRWLockCreate(__FILE__, __LINE__, lock) + + /* Report that the lock at address "lock" is about to be destroyed. */ + #define ANNOTATE_RWLOCK_DESTROY(lock) \ + AnnotateRWLockDestroy(__FILE__, __LINE__, lock) + + /* Report that the lock at address "lock" has been acquired. + is_w=1 for writer lock, is_w=0 for reader lock. */ + #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ + AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w) + + /* Report that the lock at address "lock" is about to be released. */ + #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ + AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w) + + /* ------------------------------------------------------------- + Annotations useful when implementing barriers. They are not + normally needed by modules that merely use barriers. + The "barrier" argument is a pointer to the barrier object. */ + + /* Report that the "barrier" has been initialized with initial "count". + If 'reinitialization_allowed' is true, initialization is allowed to happen + multiple times w/o calling barrier_destroy() */ + #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \ + AnnotateBarrierInit(__FILE__, __LINE__, barrier, count, \ + reinitialization_allowed) + + /* Report that we are about to enter barrier_wait("barrier"). */ + #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \ + AnnotateBarrierWaitBefore(__FILE__, __LINE__, barrier) + + /* Report that we just exited barrier_wait("barrier"). */ + #define ANNOTATE_BARRIER_WAIT_AFTER(barrier) \ + AnnotateBarrierWaitAfter(__FILE__, __LINE__, barrier) + + /* Report that the "barrier" has been destroyed. */ + #define ANNOTATE_BARRIER_DESTROY(barrier) \ + AnnotateBarrierDestroy(__FILE__, __LINE__, barrier) + + /* ------------------------------------------------------------- + Annotations useful for testing race detectors. */ + + /* Report that we expect a race on the variable at "address". + Use only in unit tests for a race detector. */ + #define ANNOTATE_EXPECT_RACE(address, description) \ + AnnotateExpectRace(__FILE__, __LINE__, address, description) + + /* A no-op. Insert where you like to test the interceptors. */ + #define ANNOTATE_NO_OP(arg) \ + AnnotateNoOp(__FILE__, __LINE__, arg) + + /* Force the race detector to flush its state. The actual effect depends on + * the implementation of the detector. */ + #define ANNOTATE_FLUSH_STATE() \ + AnnotateFlushState(__FILE__, __LINE__) + + +#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ + + #define ANNOTATE_RWLOCK_CREATE(lock) /* empty */ + #define ANNOTATE_RWLOCK_DESTROY(lock) /* empty */ + #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */ + #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */ + #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) /* */ + #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) /* empty */ + #define ANNOTATE_BARRIER_WAIT_AFTER(barrier) /* empty */ + #define ANNOTATE_BARRIER_DESTROY(barrier) /* empty */ + #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) /* empty */ + #define ANNOTATE_CONDVAR_WAIT(cv) /* empty */ + #define ANNOTATE_CONDVAR_SIGNAL(cv) /* empty */ + #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) /* empty */ + #define ANNOTATE_HAPPENS_BEFORE(obj) /* empty */ + #define ANNOTATE_HAPPENS_AFTER(obj) /* empty */ + #define ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) /* empty */ + #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(address, size) /* empty */ + #define ANNOTATE_SWAP_MEMORY_RANGE(address, size) /* empty */ + #define ANNOTATE_PCQ_CREATE(pcq) /* empty */ + #define ANNOTATE_PCQ_DESTROY(pcq) /* empty */ + #define ANNOTATE_PCQ_PUT(pcq) /* empty */ + #define ANNOTATE_PCQ_GET(pcq) /* empty */ + #define ANNOTATE_NEW_MEMORY(address, size) /* empty */ + #define ANNOTATE_EXPECT_RACE(address, description) /* empty */ + #define ANNOTATE_BENIGN_RACE(address, description) /* empty */ + #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */ + #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */ + #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */ + #define ANNOTATE_TRACE_MEMORY(arg) /* empty */ + #define ANNOTATE_THREAD_NAME(name) /* empty */ + #define ANNOTATE_IGNORE_READS_BEGIN() /* empty */ + #define ANNOTATE_IGNORE_READS_END() /* empty */ + #define ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */ + #define ANNOTATE_IGNORE_WRITES_END() /* empty */ + #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */ + #define ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */ + #define ANNOTATE_IGNORE_SYNC_BEGIN() /* empty */ + #define ANNOTATE_IGNORE_SYNC_END() /* empty */ + #define ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */ + #define ANNOTATE_NO_OP(arg) /* empty */ + #define ANNOTATE_FLUSH_STATE() /* empty */ + +#endif /* DYNAMIC_ANNOTATIONS_ENABLED */ + +/* Use the macros above rather than using these functions directly. */ +#ifdef __cplusplus +extern "C" { +#endif +void AnnotateRWLockCreate(const char *file, int line, + const volatile void *lock); +void AnnotateRWLockDestroy(const char *file, int line, + const volatile void *lock); +void AnnotateRWLockAcquired(const char *file, int line, + const volatile void *lock, long is_w); +void AnnotateRWLockReleased(const char *file, int line, + const volatile void *lock, long is_w); +void AnnotateBarrierInit(const char *file, int line, + const volatile void *barrier, long count, + long reinitialization_allowed); +void AnnotateBarrierWaitBefore(const char *file, int line, + const volatile void *barrier); +void AnnotateBarrierWaitAfter(const char *file, int line, + const volatile void *barrier); +void AnnotateBarrierDestroy(const char *file, int line, + const volatile void *barrier); +void AnnotateCondVarWait(const char *file, int line, + const volatile void *cv, + const volatile void *lock); +void AnnotateCondVarSignal(const char *file, int line, + const volatile void *cv); +void AnnotateCondVarSignalAll(const char *file, int line, + const volatile void *cv); +void AnnotatePublishMemoryRange(const char *file, int line, + const volatile void *address, + long size); +void AnnotateUnpublishMemoryRange(const char *file, int line, + const volatile void *address, + long size); +void AnnotatePCQCreate(const char *file, int line, + const volatile void *pcq); +void AnnotatePCQDestroy(const char *file, int line, + const volatile void *pcq); +void AnnotatePCQPut(const char *file, int line, + const volatile void *pcq); +void AnnotatePCQGet(const char *file, int line, + const volatile void *pcq); +void AnnotateNewMemory(const char *file, int line, + const volatile void *address, + long size); +void AnnotateExpectRace(const char *file, int line, + const volatile void *address, + const char *description); +void AnnotateBenignRace(const char *file, int line, + const volatile void *address, + const char *description); +void AnnotateBenignRaceSized(const char *file, int line, + const volatile void *address, + long size, + const char *description); +void AnnotateMutexIsUsedAsCondVar(const char *file, int line, + const volatile void *mu); +void AnnotateTraceMemory(const char *file, int line, + 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); +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); + +/* Return non-zero value if running under valgrind. + + If "valgrind.h" is included into dynamic_annotations.c, + the regular valgrind mechanism will be used. + See http://valgrind.org/docs/manual/manual-core-adv.html about + RUNNING_ON_VALGRIND and other valgrind "client requests". + The file "valgrind.h" may be obtained by doing + svn co svn://svn.valgrind.org/valgrind/trunk/include + + If for some reason you can't use "valgrind.h" or want to fake valgrind, + there are two ways to make this function return non-zero: + - Use environment variable: export RUNNING_ON_VALGRIND=1 + - Make your tool intercept the function RunningOnValgrind() and + change its return value. + */ +int RunningOnValgrind(void); + +#ifdef __cplusplus +} +#endif + +#if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus) + + /* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. + + Instead of doing + ANNOTATE_IGNORE_READS_BEGIN(); + ... = x; + ANNOTATE_IGNORE_READS_END(); + one can use + ... = ANNOTATE_UNPROTECTED_READ(x); */ + template <class T> + inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) { + ANNOTATE_IGNORE_READS_BEGIN(); + T res = x; + ANNOTATE_IGNORE_READS_END(); + return res; + } + /* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */ + #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ + namespace { \ + class static_var ## _annotator { \ + public: \ + static_var ## _annotator() { \ + ANNOTATE_BENIGN_RACE_SIZED(&static_var, \ + sizeof(static_var), \ + # static_var ": " description); \ + } \ + }; \ + static static_var ## _annotator the ## static_var ## _annotator;\ + } +#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ + + #define ANNOTATE_UNPROTECTED_READ(x) (x) + #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */ + +#endif /* DYNAMIC_ANNOTATIONS_ENABLED */ + +#endif /* __DYNAMIC_ANNOTATIONS_H__ */ diff --git a/base/thread.cc b/base/thread.cc index a81fcb4..e3c335a 100644 --- a/base/thread.cc +++ b/base/thread.cc @@ -4,9 +4,9 @@ #include "base/thread.h" -#include "base/dynamic_annotations.h" #include "base/lazy_instance.h" #include "base/string_util.h" +#include "base/third_party/dynamic_annotations/dynamic_annotations.h" #include "base/thread_local.h" #include "base/waitable_event.h" diff --git a/base/thread_unittest.cc b/base/thread_unittest.cc index 4ceeb80..696cfc2a9 100644 --- a/base/thread_unittest.cc +++ b/base/thread_unittest.cc @@ -6,10 +6,10 @@ #include <vector> -#include "base/dynamic_annotations.h" #include "base/lock.h" #include "base/message_loop.h" #include "base/string_util.h" +#include "base/third_party/dynamic_annotations/dynamic_annotations.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" diff --git a/base/tools_sanity_unittest.cc b/base/tools_sanity_unittest.cc index f4d4df9..3023059 100644 --- a/base/tools_sanity_unittest.cc +++ b/base/tools_sanity_unittest.cc @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/dynamic_annotations.h" #include "base/message_loop.h" +#include "base/third_party/dynamic_annotations/dynamic_annotations.h" #include "base/thread.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/build/common.gypi b/build/common.gypi index 6aad1932..f457a2b 100644 --- a/build/common.gypi +++ b/build/common.gypi @@ -622,6 +622,7 @@ }, 'Debug_Base': { 'abstract': 1, + 'defines': ['DYNAMIC_ANNOTATIONS_ENABLED=1'], 'xcode_settings': { 'COPY_PHASE_STRIP': 'NO', 'GCC_OPTIMIZATION_LEVEL': '<(mac_debug_optimization)', @@ -694,7 +695,9 @@ }, 'conditions': [ ['release_valgrind_build==0', { - 'defines': ['NVALGRIND'], + 'defines': ['NVALGRIND', 'DYNAMIC_ANNOTATIONS_ENABLED=0'], + }, { + 'defines': ['DYNAMIC_ANNOTATIONS_ENABLED=1'], }], ['win_use_allocator_shim==0', { 'defines': ['NO_TCMALLOC'], diff --git a/chrome/browser/geolocation/wifi_data_provider_common_unittest.cc b/chrome/browser/geolocation/wifi_data_provider_common_unittest.cc index 239e583c6..be165a7 100644 --- a/chrome/browser/geolocation/wifi_data_provider_common_unittest.cc +++ b/chrome/browser/geolocation/wifi_data_provider_common_unittest.cc @@ -6,9 +6,9 @@ #include <vector> -#include "base/dynamic_annotations.h" #include "base/scoped_ptr.h" #include "base/string_util.h" +#include "base/third_party/dynamic_annotations/dynamic_annotations.h" #include "testing/gtest/include/gtest/gtest.h" class MockWlanApi : public WifiDataProviderCommon::WlanApiInterface { diff --git a/chrome/browser/sync/engine/syncer_thread.cc b/chrome/browser/sync/engine/syncer_thread.cc index 6da8e70..c543f6a 100644 --- a/chrome/browser/sync/engine/syncer_thread.cc +++ b/chrome/browser/sync/engine/syncer_thread.cc @@ -15,7 +15,7 @@ #include <map> #include <queue> -#include "base/dynamic_annotations.h" +#include "base/third_party/dynamic_annotations/dynamic_annotations.h" #include "chrome/browser/sync/sync_constants.h" #include "chrome/browser/sync/engine/auth_watcher.h" #include "chrome/browser/sync/engine/model_safe_worker.h" diff --git a/chrome/browser/sync/glue/ui_model_worker.cc b/chrome/browser/sync/glue/ui_model_worker.cc index d1a12b6..2d08aa5 100644 --- a/chrome/browser/sync/glue/ui_model_worker.cc +++ b/chrome/browser/sync/glue/ui_model_worker.cc @@ -4,8 +4,8 @@ #include "chrome/browser/sync/glue/ui_model_worker.h" -#include "base/dynamic_annotations.h" #include "base/message_loop.h" +#include "base/third_party/dynamic_annotations/dynamic_annotations.h" #include "base/waitable_event.h" namespace browser_sync { diff --git a/ipc/ipc_sync_channel_unittest.cc b/ipc/ipc_sync_channel_unittest.cc index 6033c21..13e9a1f 100644 --- a/ipc/ipc_sync_channel_unittest.cc +++ b/ipc/ipc_sync_channel_unittest.cc @@ -8,12 +8,12 @@ #include <vector> #include "base/basictypes.h" -#include "base/dynamic_annotations.h" #include "base/logging.h" #include "base/message_loop.h" #include "base/platform_thread.h" #include "base/stl_util-inl.h" #include "base/string_util.h" +#include "base/third_party/dynamic_annotations/dynamic_annotations.h" #include "base/thread.h" #include "base/waitable_event.h" #include "ipc/ipc_message.h" diff --git a/net/socket/tcp_pinger.h b/net/socket/tcp_pinger.h index f557e25..96fa4fd 100644 --- a/net/socket/tcp_pinger.h +++ b/net/socket/tcp_pinger.h @@ -6,10 +6,10 @@ #define NET_SOCKET_TCP_PINGER_H_ #include "base/compiler_specific.h" -#include "base/dynamic_annotations.h" #include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "base/task.h" +#include "base/third_party/dynamic_annotations/dynamic_annotations.h" #include "base/thread.h" #include "base/waitable_event.h" #include "net/base/address_list.h" |