diff options
author | Andy Hung <hunga@google.com> | 2023-12-14 10:05:20 -0800 |
---|---|---|
committer | Andy Hung <hunga@google.com> | 2024-03-07 20:56:59 -0800 |
commit | d194fd7e990d4430ee419b242936c8c298b4e86a (patch) | |
tree | 4c0d4e6b62382207735dec1a974ef1d11c75bd8c | |
parent | aa7f441d06e5895d05269b08a7e8b494fb0c61eb (diff) | |
download | media-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.cpp | 62 |
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). |