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;
}