summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Hung <hunga@google.com>2023-12-14 10:05:20 -0800
committerAndy Hung <hunga@google.com>2024-03-07 20:56:59 -0800
commitd194fd7e990d4430ee419b242936c8c298b4e86a (patch)
tree4c0d4e6b62382207735dec1a974ef1d11c75bd8c
parentaa7f441d06e5895d05269b08a7e8b494fb0c61eb (diff)
downloadmedia-d194fd7e990d4430ee419b242936c8c298b4e86a.tar.gz
audio_mutex_tests: Verify timed try_lock waits long enough
This also requires bionic fix 5e19b185fdccbccca76e2925d3b0a1c6c80ad937 Test: atest audio_mutex_tests Bug: 312787238 Merged-In: I1f40f9c0eb389952af84e78a2687e4dcf9b5d31d Change-Id: I1f40f9c0eb389952af84e78a2687e4dcf9b5d31d
-rw-r--r--audio_utils/tests/audio_mutex_tests.cpp62
1 files changed, 62 insertions, 0 deletions
diff --git a/audio_utils/tests/audio_mutex_tests.cpp b/audio_utils/tests/audio_mutex_tests.cpp
index 17e98744..5cc860d8 100644
--- a/audio_utils/tests/audio_mutex_tests.cpp
+++ b/audio_utils/tests/audio_mutex_tests.cpp
@@ -427,6 +427,68 @@ NO_THREAD_SAFETY_ANALYSIS {
ASSERT_DEATH(m1.unlock(), ".*mutex unlock.*");
}
+TEST(audio_mutex_tests, TimedLock) {
+ using ConditionVariable = android::audio_utils::condition_variable;
+ using Mutex = android::audio_utils::mutex;
+ using UniqueLock = android::audio_utils::unique_lock;
+ Mutex m, m1;
+ ConditionVariable cv;
+ bool quit = false; // GUARDED_BY(m)
+
+ std::atomic<pid_t> tid1{};
+
+ // launch thread.
+ std::thread t1([&]() {
+ UniqueLock ul1(m1);
+ UniqueLock ul(m);
+ tid1 = android::audio_utils::gettid_wrapper();
+ while (!quit) {
+ cv.wait(ul, [&]{ return quit; });
+ if (quit) break;
+ }
+ });
+
+ // ensure thread tid1 has acquired all locks.
+ while (tid1 == 0) { usleep(1000); }
+
+ // try lock for 1s
+ constexpr int64_t kTimeoutNs = 1'000'000'000;
+ {
+ // verify timed out state.
+ const int64_t beginNs = systemTime();
+ const bool success = m1.try_lock(kTimeoutNs);
+ const int64_t endNs = systemTime();
+ const int64_t diffNs = endNs - beginNs;
+
+ if (success) m1.unlock();
+ EXPECT_GT(diffNs, kTimeoutNs);
+ EXPECT_FALSE(success);
+ }
+
+ // exit the thread
+ {
+ UniqueLock ul(m);
+
+ quit = true;
+ cv.notify_one();
+ }
+
+ t1.join();
+
+ {
+ // verify success state.
+ const int64_t beginNs = systemTime();
+ const bool success = m1.try_lock(kTimeoutNs);
+ const int64_t endNs = systemTime();
+ const int64_t diffNs = endNs - beginNs;
+
+ if (success) m1.unlock();
+ constexpr int64_t kSuccessLockNs = kTimeoutNs / 4;
+ EXPECT_LT(diffNs, kSuccessLockNs);
+ EXPECT_TRUE(success);
+ }
+}
+
// Test the deadlock detection algorithm for a single wait chain
// (no cycle).