tsan: implement RWLOCK annotations


git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@162019 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc
index de6985a..1dce12b 100644
--- a/lib/tsan/rtl/tsan_interceptors.cc
+++ b/lib/tsan/rtl/tsan_interceptors.cc
@@ -782,7 +782,7 @@
         recursive = (type == PTHREAD_MUTEX_RECURSIVE
             || type == PTHREAD_MUTEX_RECURSIVE_NP);
     }
-    MutexCreate(thr, pc, (uptr)m, false, recursive);
+    MutexCreate(thr, pc, (uptr)m, false, recursive, false);
   }
   return res;
 }
@@ -834,7 +834,7 @@
   SCOPED_TSAN_INTERCEPTOR(pthread_spin_init, m, pshared);
   int res = REAL(pthread_spin_init)(m, pshared);
   if (res == 0) {
-    MutexCreate(thr, pc, (uptr)m, false, false);
+    MutexCreate(thr, pc, (uptr)m, false, false, false);
   }
   return res;
 }
@@ -877,7 +877,7 @@
   SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_init, m, a);
   int res = REAL(pthread_rwlock_init)(m, a);
   if (res == 0) {
-    MutexCreate(thr, pc, (uptr)m, true, false);
+    MutexCreate(thr, pc, (uptr)m, true, false, false);
   }
   return res;
 }
diff --git a/lib/tsan/rtl/tsan_interface_ann.cc b/lib/tsan/rtl/tsan_interface_ann.cc
index a605b6c..975cdba 100644
--- a/lib/tsan/rtl/tsan_interface_ann.cc
+++ b/lib/tsan/rtl/tsan_interface_ann.cc
@@ -52,11 +52,11 @@
     if (!flags()->enable_annotations) \
       return; \
     ThreadState *thr = cur_thread(); \
+    const uptr pc = (uptr)__builtin_return_address(0); \
     StatInc(thr, StatAnnotation); \
     StatInc(thr, Stat##typ); \
     ScopedAnnotation sa(thr, __FUNCTION__, f, l, \
         (uptr)__builtin_return_address(0)); \
-    const uptr pc = (uptr)&__FUNCTION__; \
     (void)pc; \
 /**/
 
@@ -185,20 +185,35 @@
   SCOPED_ANNOTATION(AnnotateCondVarWait);
 }
 
-void AnnotateRWLockCreate(char *f, int l, uptr lock) {
+void AnnotateRWLockCreate(char *f, int l, uptr m) {
   SCOPED_ANNOTATION(AnnotateRWLockCreate);
+  MutexCreate(thr, pc, m, true, true, false);
 }
 
-void AnnotateRWLockDestroy(char *f, int l, uptr lock) {
+void AnnotateRWLockCreateStatic(char *f, int l, uptr m) {
+  SCOPED_ANNOTATION(AnnotateRWLockCreateStatic);
+  MutexCreate(thr, pc, m, true, true, true);
+}
+
+void AnnotateRWLockDestroy(char *f, int l, uptr m) {
   SCOPED_ANNOTATION(AnnotateRWLockDestroy);
+  MutexDestroy(thr, pc, m);
 }
 
-void AnnotateRWLockAcquired(char *f, int l, uptr lock, uptr is_w) {
+void AnnotateRWLockAcquired(char *f, int l, uptr m, uptr is_w) {
   SCOPED_ANNOTATION(AnnotateRWLockAcquired);
+  if (is_w)
+    MutexLock(thr, pc, m);
+  else
+    MutexReadLock(thr, pc, m);
 }
 
-void AnnotateRWLockReleased(char *f, int l, uptr lock, uptr is_w) {
+void AnnotateRWLockReleased(char *f, int l, uptr m, uptr is_w) {
   SCOPED_ANNOTATION(AnnotateRWLockReleased);
+  if (is_w)
+    MutexUnlock(thr, pc, m);
+  else
+    MutexReadUnlock(thr, pc, m);
 }
 
 void AnnotateTraceMemory(char *f, int l, uptr mem) {
diff --git a/lib/tsan/rtl/tsan_rtl.h b/lib/tsan/rtl/tsan_rtl.h
index b7d0c13..336b656 100644
--- a/lib/tsan/rtl/tsan_rtl.h
+++ b/lib/tsan/rtl/tsan_rtl.h
@@ -468,7 +468,8 @@
 void ThreadFinalize(ThreadState *thr);
 void ThreadFinalizerGoroutine(ThreadState *thr);
 
-void MutexCreate(ThreadState *thr, uptr pc, uptr addr, bool rw, bool recursive);
+void MutexCreate(ThreadState *thr, uptr pc, uptr addr,
+                 bool rw, bool recursive, bool linker_init);
 void MutexDestroy(ThreadState *thr, uptr pc, uptr addr);
 void MutexLock(ThreadState *thr, uptr pc, uptr addr);
 void MutexUnlock(ThreadState *thr, uptr pc, uptr addr);
diff --git a/lib/tsan/rtl/tsan_rtl_mutex.cc b/lib/tsan/rtl/tsan_rtl_mutex.cc
index 882def8..9e7c78d 100644
--- a/lib/tsan/rtl/tsan_rtl_mutex.cc
+++ b/lib/tsan/rtl/tsan_rtl_mutex.cc
@@ -19,7 +19,7 @@
 namespace __tsan {
 
 void MutexCreate(ThreadState *thr, uptr pc, uptr addr,
-                 bool rw, bool recursive) {
+                 bool rw, bool recursive, bool linker_init) {
   Context *ctx = CTX();
   CHECK_GT(thr->in_rtl, 0);
   DPrintf("#%d: MutexCreate %zx\n", thr->tid, addr);
diff --git a/lib/tsan/rtl/tsan_stat.h b/lib/tsan/rtl/tsan_stat.h
index 71b1b13..6bc5d23 100644
--- a/lib/tsan/rtl/tsan_stat.h
+++ b/lib/tsan/rtl/tsan_stat.h
@@ -209,6 +209,7 @@
   StatAnnotateMutexIsNotPHB,
   StatAnnotateCondVarWait,
   StatAnnotateRWLockCreate,
+  StatAnnotateRWLockCreateStatic,
   StatAnnotateRWLockDestroy,
   StatAnnotateRWLockAcquired,
   StatAnnotateRWLockReleased,