get rid of intermittent tsan false failures

Change-Id: Iccf7ac7ec11326459e6f8c0ebd5621319139cc01
diff --git a/aos/common/mutex_test.cc b/aos/common/mutex_test.cc
index bd2365a..56f7772 100644
--- a/aos/common/mutex_test.cc
+++ b/aos/common/mutex_test.cc
@@ -4,6 +4,8 @@
 #include <math.h>
 #include <pthread.h>
 
+#include <thread>
+
 #include "gtest/gtest.h"
 
 #include "aos/linux_code/ipc_lib/aos_sync.h"
@@ -145,6 +147,24 @@
   EXPECT_EQ(2, counter);
 }
 
+// Verifiers that ThreadSanitizer understands how a mutex works.
+// For some reason this used to fail when the other tests didn't...
+TEST_F(MutexTest, ThreadSanitizerMutexLocker) {
+  int counter = 0;
+  ::std::thread thread([&counter, this]() {
+    for (int i = 0; i < 1000; ++i) {
+      MutexLocker locker(&test_mutex);
+      ++counter;
+    }
+  });
+  for (int i = 0; i < 1000; ++i) {
+    MutexLocker locker(&test_mutex);
+    --counter;
+  }
+  thread.join();
+  EXPECT_EQ(0, counter);
+}
+
 // Verifies that ThreadSanitizer understands that an uncontended mutex
 // establishes a happens-before relationship.
 TEST_F(MutexTest, ThreadSanitizerUncontended) {
diff --git a/aos/linux_code/ipc_lib/aos_sync.cc b/aos/linux_code/ipc_lib/aos_sync.cc
index efda532..ffd1061 100644
--- a/aos/linux_code/ipc_lib/aos_sync.cc
+++ b/aos/linux_code/ipc_lib/aos_sync.cc
@@ -155,21 +155,10 @@
 }
 
 // Returns true if it succeeds and false if it fails.
-// This is the same as __sync_bool_compare_and_swap, except it fixes that being
-// broken under tsan.
+// This is the same as __sync_bool_compare_and_swap, except it provides an easy
+// place to switch implementations and/or work around bugs.
 inline bool compare_and_swap(aos_futex *f, uint32_t before, uint32_t after) {
-#ifdef AOS_SANITIZER_thread
-  // TODO(brians): Figure out how exactly tsan breaks this and fix it + make
-  // sure our workaround actually works.
-  // This workaround is unsafe in the general case, but does not change the
-  // effect in our specific case if the primitive works correctly (and seems to
-  // still do the right thing even when tsan's version falsely reports failing).
-  if (__atomic_load_n(f, __ATOMIC_SEQ_CST) == after) return false;
-  if (__sync_bool_compare_and_swap(f, before, after)) return true;
-  return __atomic_load_n(f, __ATOMIC_SEQ_CST) == after;
-#else
   return __sync_bool_compare_and_swap(f, before, after);
-#endif
 }
 
 pid_t do_get_tid() {
@@ -267,6 +256,11 @@
     }
   }
 
+#ifdef AOS_SANITIZER_thread
+  // Help tsan figure out that we're synchronizing on this.
+  __sync_fetch_and_add(&m->futex, 0);
+#endif
+
   return 0;
 }