|
From: <sv...@va...> - 2010-03-07 10:42:25
|
Author: bart
Date: 2010-03-07 10:42:15 +0000 (Sun, 07 Mar 2010)
New Revision: 11067
Log:
Made the behavior of the annotate_smart_pointer test program configurable
through command-line arguments, and made sure that the annotations present
in the source code are recognized by all Valgrind-based data race detection
tools.
Added:
trunk/drd/tests/unified_annotations.h
Modified:
trunk/drd/tests/annotate_smart_pointer.cpp
Modified: trunk/drd/tests/annotate_smart_pointer.cpp
===================================================================
--- trunk/drd/tests/annotate_smart_pointer.cpp 2010-03-06 19:38:56 UTC (rev 11066)
+++ trunk/drd/tests/annotate_smart_pointer.cpp 2010-03-07 10:42:15 UTC (rev 11067)
@@ -27,7 +27,7 @@
#include <cassert> // assert()
#include <climits> // PTHREAD_STACK_MIN
-#include <iostream> // std::cout
+#include <iostream> // std::cerr
#include <stdlib.h> // atoi()
#ifdef _WIN32
#include <process.h> // _beginthreadex()
@@ -35,9 +35,12 @@
#else
#include <pthread.h> // pthread_mutex_t
#endif
-#include "../../drd/drd.h"
+#include "unified_annotations.h"
+static bool s_enable_annotations = true;
+
+
#ifdef _WIN32
class AtomicInt32
@@ -232,10 +235,15 @@
{
if (m_count_ptr)
{
- ANNOTATE_HAPPENS_BEFORE(m_count_ptr);
+ if (s_enable_annotations)
+ ANNOTATE_HAPPENS_BEFORE(m_count_ptr);
if (--(*m_count_ptr) == 0)
{
- ANNOTATE_HAPPENS_AFTER(m_count_ptr);
+ if (s_enable_annotations)
+ {
+ ANNOTATE_HAPPENS_AFTER(m_count_ptr);
+ ANNOTATE_HAPPENS_DONE(m_count_ptr);
+ }
delete m_ptr;
m_ptr = NULL;
delete m_count_ptr;
@@ -300,17 +308,23 @@
int main(int argc, char** argv)
{
- smart_ptr<counter> p(new counter);
const int nthreads = std::max(argc > 1 ? atoi(argv[1]) : 1, 1);
- Thread T[nthreads];
+ const int iterations = std::max(argc > 2 ? atoi(argv[2]) : 1, 1);
+ s_enable_annotations = argc > 3 ? !!atoi(argv[3]) : true;
- p->post_increment();
- for (int i = 0; i < nthreads; ++i)
- T[i].Create(thread_func, new smart_ptr<counter>(p));
- p = NULL;
- for (int i = 0; i < nthreads; ++i)
- T[i].Join();
- std::cout << "Done.\n";
+ for (int j = 0; j < iterations; ++j)
+ {
+ Thread T[nthreads];
+
+ smart_ptr<counter> p(new counter);
+ p->post_increment();
+ for (int i = 0; i < nthreads; ++i)
+ T[i].Create(thread_func, new smart_ptr<counter>(p));
+ p = NULL;
+ for (int i = 0; i < nthreads; ++i)
+ T[i].Join();
+ }
+ std::cerr << "Done.\n";
return 0;
}
Added: trunk/drd/tests/unified_annotations.h
===================================================================
--- trunk/drd/tests/unified_annotations.h (rev 0)
+++ trunk/drd/tests/unified_annotations.h 2010-03-07 10:42:15 UTC (rev 11067)
@@ -0,0 +1,68 @@
+#ifndef _UNIFIED_ANNOTATIONS_H_
+#define _UNIFIED_ANNOTATIONS_H_
+
+
+#include "../../drd/drd.h"
+
+
+/*
+ * Redefine the happens before/after/done annotation macros such that these
+ * can be intercepted by DRD, Helgrind and ThreadSanitizer. See also
+ * http://code.google.com/p/data-race-test/source/browse/trunk/dynamic_annotations/dynamic_annotations.h
+ */
+#undef ANNOTATE_HAPPENS_BEFORE
+#define ANNOTATE_HAPPENS_BEFORE(addr) \
+ do { \
+ DRDCL_(annotate_happens_before)(addr); \
+ AnnotateCondVarSignal(__FILE__, __LINE__, addr); \
+ } while(0)
+#undef ANNOTATE_HAPPENS_AFTER
+#define ANNOTATE_HAPPENS_AFTER(addr) \
+ do { \
+ DRDCL_(annotate_happens_after)(addr); \
+ AnnotateCondVarWait(__FILE__, __LINE__, addr, NULL); \
+ } while(0)
+#undef ANNOTATE_HAPPENS_DONE
+#define ANNOTATE_HAPPENS_DONE(addr) \
+ do { \
+ DRDCL_(annotate_happens_done)(addr); \
+ } while(0)
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if 0
+}
+#endif
+
+
+void __attribute__((weak,noinline))
+AnnotateCondVarSignal(const char *file, int line, const volatile void *cv)
+{
+ asm("");
+}
+
+void __attribute__((weak,noinline))
+AnnotateCondVarWait(const char *file, int line, const volatile void *cv,
+ const volatile void *lock)
+{
+ asm("");
+}
+
+
+#if 0
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _UNIFIED_ANNOTATIONS_H_ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 2
+ * End:
+ */
|