[compiler-rt] r235293 - tsan: fix handling of pthread_detach
Dmitry Vyukov
dvyukov at google.com
Mon Apr 20 03:35:10 PDT 2015
Author: dvyukov
Date: Mon Apr 20 05:35:10 2015
New Revision: 235293
URL: http://llvm.org/viewvc/llvm-project?rev=235293&view=rev
Log:
tsan: fix handling of pthread_detach
Fixes https://llvm.org/bugs/show_bug.cgi?id=23235
If pthread_create is followed by pthread_detach,
the new thread may not acquire synchronize with
the parent thread.
Added:
compiler-rt/trunk/test/tsan/thread_detach2.c
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=235293&r1=235292&r2=235293&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Mon Apr 20 05:35:10 2015
@@ -935,8 +935,8 @@ extern "C" void *__tsan_thread_start_fun
ThreadIgnoreEnd(thr, 0);
while ((tid = atomic_load(&p->tid, memory_order_acquire)) == 0)
pthread_yield();
- atomic_store(&p->tid, 0, memory_order_release);
ThreadStart(thr, tid, GetTid());
+ atomic_store(&p->tid, 0, memory_order_release);
}
void *res = callback(param);
// Prevent the callback from being tail called,
@@ -984,6 +984,13 @@ TSAN_INTERCEPTOR(int, pthread_create,
if (res == 0) {
int tid = ThreadCreate(thr, pc, *(uptr*)th, detached);
CHECK_NE(tid, 0);
+ // Synchronization on p.tid serves two purposes:
+ // 1. ThreadCreate must finish before the new thread starts.
+ // Otherwise the new thread can call pthread_detach, but the pthread_t
+ // identifier is not yet registered in ThreadRegistry by ThreadCreate.
+ // 2. ThreadStart must finish before this thread continues.
+ // Otherwise, this thread can call pthread_detach and reset thr->sync
+ // before the new thread got a chance to acquire from it in ThreadStart.
atomic_store(&p.tid, tid, memory_order_release);
while (atomic_load(&p.tid, memory_order_acquire) != 0)
pthread_yield();
Added: compiler-rt/trunk/test/tsan/thread_detach2.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/thread_detach2.c?rev=235293&view=auto
==============================================================================
--- compiler-rt/trunk/test/tsan/thread_detach2.c (added)
+++ compiler-rt/trunk/test/tsan/thread_detach2.c Mon Apr 20 05:35:10 2015
@@ -0,0 +1,28 @@
+// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+#include "test.h"
+
+// Test for https://llvm.org/bugs/show_bug.cgi?id=23235
+// The bug was that synchronization between thread creation and thread start
+// is not established if pthread_create is followed by pthread_detach.
+
+int x;
+
+void *Thread(void *a) {
+ x = 42;
+ barrier_wait(&barrier);
+ return 0;
+}
+
+int main() {
+ barrier_init(&barrier, 2);
+ pthread_t t;
+ x = 43;
+ pthread_create(&t, 0, Thread, 0);
+ pthread_detach(t);
+ barrier_wait(&barrier);
+ printf("PASS\n");
+ return 0;
+}
+
+// CHECK-NOT: WARNING: ThreadSanitizer: data race
+// CHECK: PASS
More information about the llvm-commits
mailing list