Skip to content

Commit

Permalink
Added dynamic annotation files into base/.
Browse files Browse the repository at this point in the history
Added annotations for atomic reference counting, LazyInstance and Singleton classes.

This changelist is a part of an effort of adding ThreadSanitizer support for Chromium.
See http://code.google.com/p/data-race-test/wiki/ThreadSanitizer

Patch by Timur Iskhodzhanov.

Review URL: http://codereview.chromium.org/147008


git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19353 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
deanm@chromium.org committed Jun 26, 2009
1 parent 09e5f47 commit 001b694
Show file tree
Hide file tree
Showing 7 changed files with 468 additions and 4 deletions.
23 changes: 20 additions & 3 deletions base/atomic_ref_count.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@

// This is a low level implementation of atomic semantics for reference
// counting. Please use base/ref_counted.h directly instead.
//
// The implementation includes annotations to avoid some false positives
// when using data race detection tools.

#ifndef BASE_ATOMIC_REF_COUNT_H_
#define BASE_ATOMIC_REF_COUNT_H_

#include "base/atomicops.h"
#include "base/dynamic_annotations.h"

namespace base {

Expand All @@ -26,7 +30,12 @@ inline void AtomicRefCountIncN(volatile AtomicRefCount *ptr,
// became zero will be visible to a thread that has just made the count zero.
inline bool AtomicRefCountDecN(volatile AtomicRefCount *ptr,
AtomicRefCount decrement) {
return subtle::Barrier_AtomicIncrement(ptr, -decrement) != 0;
ANNOTATE_HAPPENS_BEFORE(ptr);
bool res = (subtle::Barrier_AtomicIncrement(ptr, -decrement) != 0);
if (!res) {
ANNOTATE_HAPPENS_AFTER(ptr);
}
return res;
}

// Increment a reference count by 1.
Expand All @@ -48,14 +57,22 @@ inline bool AtomicRefCountDec(volatile AtomicRefCount *ptr) {
// needed for the owning thread to act on the object, knowing that it has
// exclusive access to the object.
inline bool AtomicRefCountIsOne(volatile AtomicRefCount *ptr) {
return subtle::Acquire_Load(ptr) == 1;
bool res = (subtle::Acquire_Load(ptr) == 1);
if (res) {
ANNOTATE_HAPPENS_AFTER(ptr);
}
return res;
}

// Return whether the reference count is zero. With conventional object
// referencing counting, the object will be destroyed, so the reference count
// should never be zero. Hence this is generally used for a debug check.
inline bool AtomicRefCountIsZero(volatile AtomicRefCount *ptr) {
return subtle::Acquire_Load(ptr) == 0;
bool res = (subtle::Acquire_Load(ptr) == 0);
if (res) {
ANNOTATE_HAPPENS_AFTER(ptr);
}
return res;
}

} // namespace base
Expand Down
2 changes: 2 additions & 0 deletions base/base.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@
'directory_watcher_inotify.cc',
'directory_watcher_mac.cc',
'directory_watcher_win.cc',
'dynamic_annotations.h',
'dynamic_annotations.cc',
'event_recorder.cc',
'event_recorder.h',
'event_recorder_stubs.cc',
Expand Down
68 changes: 68 additions & 0 deletions base/dynamic_annotations.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// 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"
#include "base/third_party/valgrind/valgrind.h"

#ifndef NDEBUG
// 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 // NDEBUG

// When running under valgrind, a non-zero value will be returned.
extern "C" int RunningOnValgrind() {
#if defined(NVALGRIND)
return 0;
#else
return RUNNING_ON_VALGRIND;
#endif
}
Loading

0 comments on commit 001b694

Please sign in to comment.