implement robust mutex support
This allows making everything in shared memory robust to
processes dying at any point in time (not actually done yet in this
commit).
This includes using FUTEX_REQUEUE_PI, but currently only on ARM because
that's the only place we can rely on the kernel not corrupting random
memory due to a bug (fix has been merged upstream).
Change-Id: Id5bda1dc3185a1aac759510934bce6fd9121ad3f
diff --git a/aos/common/condition_test.cc b/aos/common/condition_test.cc
index dbaa546..0e7bfe4 100644
--- a/aos/common/condition_test.cc
+++ b/aos/common/condition_test.cc
@@ -5,6 +5,7 @@
#include <sys/wait.h>
#include <atomic>
+#include <thread>
#include "gtest/gtest.h"
@@ -75,6 +76,22 @@
EXPECT_TRUE(child_finished.load());
}
+// Tests that contention on the associated mutex doesn't break anything.
+// This seems likely to cause issues with AddressSanitizer in particular.
+TEST_F(SimpleConditionTest, MutexContention) {
+ for (int i = 0; i < 1000; ++i) {
+ ASSERT_FALSE(mutex_.Lock());
+ ::std::thread thread([this]() {
+ ASSERT_FALSE(mutex_.Lock());
+ condition_.Signal();
+ mutex_.Unlock();
+ });
+ ASSERT_FALSE(condition_.Wait());
+ mutex_.Unlock();
+ thread.join();
+ }
+}
+
class ConditionTest : public ConditionTestCommon {
public:
struct Shared {
@@ -307,7 +324,8 @@
Settle();
shared_->condition.Signal();
EXPECT_FALSE(child.Hung());
- EXPECT_EQ(Mutex::State::kLockFailed, shared_->mutex.TryLock());
+ EXPECT_EQ(Mutex::State::kOwnerDied, shared_->mutex.TryLock());
+ shared_->mutex.Unlock();
}
// Tests that Signal() stops exactly 1 Wait()er.