[compiler-rt] r241082 - tsan: fix handling of condition variable destruction

Dmitry Vyukov dvyukov at google.com
Tue Jun 30 10:23:30 PDT 2015


Author: dvyukov
Date: Tue Jun 30 12:23:29 2015
New Revision: 241082

URL: http://llvm.org/viewvc/llvm-project?rev=241082&view=rev
Log:
tsan: fix handling of condition variable destruction

POSIX states that "It shall be safe to destroy an initialized condition
variable upon which no threads are currently blocked", and later clarifies
"A condition variable can be destroyed immediately after all the threads
that are blocked on it are awakened) (in examples section). Tsan reported
such destruction as a data race.
Fixes https://llvm.org/bugs/show_bug.cgi?id=23616
Reviewed in http://reviews.llvm.org/D10693


Added:
    compiler-rt/trunk/test/tsan/cond_destruction.cc
Modified:
    compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=241082&r1=241081&r2=241082&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Tue Jun 30 12:23:29 2015
@@ -992,8 +992,8 @@ INTERCEPTOR(int, pthread_cond_init, void
 INTERCEPTOR(int, pthread_cond_wait, void *c, void *m) {
   void *cond = init_cond(c);
   SCOPED_TSAN_INTERCEPTOR(pthread_cond_wait, cond, m);
-  MutexUnlock(thr, pc, (uptr)m);
   MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), false);
+  MutexUnlock(thr, pc, (uptr)m);
   CondMutexUnlockCtx arg = {&si, thr, pc, m};
   int res = 0;
   // This ensures that we handle mutex lock even in case of pthread_cancel.
@@ -1014,8 +1014,8 @@ INTERCEPTOR(int, pthread_cond_wait, void
 INTERCEPTOR(int, pthread_cond_timedwait, void *c, void *m, void *abstime) {
   void *cond = init_cond(c);
   SCOPED_TSAN_INTERCEPTOR(pthread_cond_timedwait, cond, m, abstime);
-  MutexUnlock(thr, pc, (uptr)m);
   MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), false);
+  MutexUnlock(thr, pc, (uptr)m);
   CondMutexUnlockCtx arg = {&si, thr, pc, m};
   int res = 0;
   // This ensures that we handle mutex lock even in case of pthread_cancel.

Added: compiler-rt/trunk/test/tsan/cond_destruction.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/cond_destruction.cc?rev=241082&view=auto
==============================================================================
--- compiler-rt/trunk/test/tsan/cond_destruction.cc (added)
+++ compiler-rt/trunk/test/tsan/cond_destruction.cc Tue Jun 30 12:23:29 2015
@@ -0,0 +1,53 @@
+// RUN: %clangxx_tsan -O1 %s -o %t
+// RUN: %run %t 2>&1 | FileCheck %s
+// RUN: %run %t arg 2>&1 | FileCheck %s
+// RUN: %run %t arg arg 2>&1 | FileCheck %s
+#include "test.h"
+
+// Test for destruction of pthread_cond_t.
+// POSIX states that it is safe  to destroy a condition variable upon which no
+// threads are currently blocked. That is, it is not necessary to wait untill
+// other threads return from pthread_cond_wait, they just need to be unblocked.
+
+pthread_mutex_t m;
+pthread_cond_t c;
+bool done1, done2;
+
+void *thr(void *p) {
+  pthread_mutex_lock(&m);
+  done1 = true;
+  pthread_cond_signal(&c);
+  while (!done2)
+    pthread_cond_wait(&c, &m);
+  pthread_mutex_unlock(&m);
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  pthread_t th;
+  pthread_mutex_init(&m, 0);
+  pthread_cond_init(&c, 0);
+  pthread_create(&th, 0, thr, 0);
+  pthread_mutex_lock(&m);
+  while (!done1)
+    pthread_cond_wait(&c, &m);
+  done2 = true;
+  // Any of these sequences is legal.
+  if (argc == 1) {
+    pthread_cond_signal(&c);
+    pthread_mutex_unlock(&m);
+    pthread_cond_destroy(&c);
+  } else if (argc == 2) {
+    pthread_mutex_unlock(&m);
+    pthread_cond_signal(&c);
+    pthread_cond_destroy(&c);
+  } else {
+    pthread_cond_signal(&c);
+    pthread_cond_destroy(&c);
+    pthread_mutex_unlock(&m);
+  }
+  pthread_join(th, 0);
+  fprintf(stderr, "DONE\n");
+}
+
+// CHECK-NOT: ThreadSanitizer: data race





More information about the llvm-commits mailing list