tsan: handle larger number of goroutines + fix a memory leak of goroutine descriptors


git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@161770 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/tsan/go/buildgo.sh b/lib/tsan/go/buildgo.sh
index a0d2f67..948ccca 100755
--- a/lib/tsan/go/buildgo.sh
+++ b/lib/tsan/go/buildgo.sh
@@ -33,7 +33,6 @@
 	../../sanitizer_common/sanitizer_libc.cc
 	../../sanitizer_common/sanitizer_posix.cc
 	../../sanitizer_common/sanitizer_printf.cc
-	../../sanitizer_common/sanitizer_symbolizer.cc
 "
 
 if [ "$LINUX" != "" ]; then
@@ -42,10 +41,10 @@
 		../../sanitizer_common/sanitizer_linux.cc
 	"
 elif [ "$MAC" != "" ]; then
-        SRCS+="
-                ../rtl/tsan_platform_mac.cc
-                ../../sanitizer_common/sanitizer_mac.cc
-        "
+	SRCS+="
+		../rtl/tsan_platform_mac.cc
+		../../sanitizer_common/sanitizer_mac.cc
+	"
 fi
 
 SRCS+=$ADD_SRCS
diff --git a/lib/tsan/go/tsan_go.cc b/lib/tsan/go/tsan_go.cc
index 4b3076c..2aa9f17 100644
--- a/lib/tsan/go/tsan_go.cc
+++ b/lib/tsan/go/tsan_go.cc
@@ -18,7 +18,9 @@
 
 namespace __tsan {
 
-static ThreadState *goroutines[kMaxTid];
+const int kMaxGoroutinesEver = 128*1024;
+
+static ThreadState *goroutines[kMaxGoroutinesEver];
 
 void InitializeInterceptors() {
 }
@@ -79,9 +81,14 @@
 extern "C" {
 
 static void AllocGoroutine(int tid) {
-  goroutines[tid] = (ThreadState*)internal_alloc(MBlockThreadContex,
+  if (tid >= kMaxGoroutinesEver) {
+    Printf("FATAL: Reached goroutine limit\n");
+    Die();
+  }
+  ThreadState *thr = (ThreadState*)internal_alloc(MBlockThreadContex,
       sizeof(ThreadState));
-  internal_memset(goroutines[tid], 0, sizeof(ThreadState));
+  internal_memset(thr, 0, sizeof(*thr));
+  goroutines[tid] = thr;
 }
 
 void __tsan_init() {
@@ -152,6 +159,8 @@
   thr->in_rtl++;
   ThreadFinish(thr);
   thr->in_rtl--;
+  internal_free(thr);
+  goroutines[goid] = 0;
 }
 
 void __tsan_acquire(int goid, void *addr) {
@@ -159,7 +168,6 @@
   thr->in_rtl++;
   Acquire(thr, 0, (uptr)addr);
   thr->in_rtl--;
-  //internal_free(thr);
 }
 
 void __tsan_release(int goid, void *addr) {