diff options
author | Scott Lobdell <slobdell@google.com> | 2019-08-25 12:20:54 -0700 |
---|---|---|
committer | Scott Lobdell <slobdell@google.com> | 2019-08-25 12:20:54 -0700 |
commit | 4f9bfdcaca2414c8959986f0a4d73f16cb15e1c4 (patch) | |
tree | 540bab5498d276cbbfad24c48a7ff989ee8b920a /tests/pthread_test.cpp | |
parent | bfda022dd6fbbcea60e9f52496d90ece514b32da (diff) | |
parent | f77cc9b224c35fa7d1d71e7c374ef19e47b5f6a5 (diff) |
Merge RP1A.190822.001
Change-Id: Iaf90835a99d87f6246798efd2cea6fe9f750ea18
Diffstat (limited to 'tests/pthread_test.cpp')
-rw-r--r-- | tests/pthread_test.cpp | 304 |
1 files changed, 274 insertions, 30 deletions
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp index 0bf8e294b..d8257381c 100644 --- a/tests/pthread_test.cpp +++ b/tests/pthread_test.cpp @@ -990,6 +990,25 @@ TEST(pthread, pthread_rwlock_reader_wakeup_writer_timedwait_monotonic_np) { #endif // __BIONIC__ } +TEST(pthread, pthread_rwlock_reader_wakeup_writer_clockwait) { +#if defined(__BIONIC__) + timespec ts; + ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts)); + ts.tv_sec += 1; + test_pthread_rwlock_reader_wakeup_writer([&](pthread_rwlock_t* lock) { + return pthread_rwlock_clockwrlock(lock, CLOCK_MONOTONIC, &ts); + }); + + ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts)); + ts.tv_sec += 1; + test_pthread_rwlock_reader_wakeup_writer([&](pthread_rwlock_t* lock) { + return pthread_rwlock_clockwrlock(lock, CLOCK_REALTIME, &ts); + }); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_rwlock_clockwrlock not available"; +#endif // __BIONIC__ +} + static void test_pthread_rwlock_writer_wakeup_reader(std::function<int (pthread_rwlock_t*)> lock_function) { RwlockWakeupHelperArg wakeup_arg; ASSERT_EQ(0, pthread_rwlock_init(&wakeup_arg.lock, nullptr)); @@ -1038,6 +1057,25 @@ TEST(pthread, pthread_rwlock_writer_wakeup_reader_timedwait_monotonic_np) { #endif // __BIONIC__ } +TEST(pthread, pthread_rwlock_writer_wakeup_reader_clockwait) { +#if defined(__BIONIC__) + timespec ts; + ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts)); + ts.tv_sec += 1; + test_pthread_rwlock_writer_wakeup_reader([&](pthread_rwlock_t* lock) { + return pthread_rwlock_clockrdlock(lock, CLOCK_MONOTONIC, &ts); + }); + + ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts)); + ts.tv_sec += 1; + test_pthread_rwlock_writer_wakeup_reader([&](pthread_rwlock_t* lock) { + return pthread_rwlock_clockrdlock(lock, CLOCK_REALTIME, &ts); + }); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_rwlock_clockrdlock not available"; +#endif // __BIONIC__ +} + static void pthread_rwlock_wakeup_timeout_helper(RwlockWakeupHelperArg* arg) { arg->tid = gettid(); ASSERT_EQ(RwlockWakeupHelperArg::LOCK_INITIALIZED, arg->progress); @@ -1098,6 +1136,38 @@ TEST(pthread, pthread_rwlock_timedrdlock_monotonic_np_timeout) { #endif // __BIONIC__ } +TEST(pthread, pthread_rwlock_clockrdlock_monotonic_timeout) { +#if defined(__BIONIC__) + pthread_rwlock_timedrdlock_timeout_helper( + CLOCK_MONOTONIC, [](pthread_rwlock_t* __rwlock, const timespec* __timeout) { + return pthread_rwlock_clockrdlock(__rwlock, CLOCK_MONOTONIC, __timeout); + }); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_rwlock_clockrdlock not available"; +#endif // __BIONIC__ +} + +TEST(pthread, pthread_rwlock_clockrdlock_realtime_timeout) { +#if defined(__BIONIC__) + pthread_rwlock_timedrdlock_timeout_helper( + CLOCK_REALTIME, [](pthread_rwlock_t* __rwlock, const timespec* __timeout) { + return pthread_rwlock_clockrdlock(__rwlock, CLOCK_REALTIME, __timeout); + }); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_rwlock_clockrdlock not available"; +#endif // __BIONIC__ +} + +TEST(pthread, pthread_rwlock_clockrdlock_invalid) { +#if defined(__BIONIC__) + pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER; + timespec ts; + EXPECT_EQ(EINVAL, pthread_rwlock_clockrdlock(&lock, CLOCK_PROCESS_CPUTIME_ID, &ts)); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_rwlock_clockrdlock not available"; +#endif // __BIONIC__ +} + static void pthread_rwlock_timedwrlock_timeout_helper( clockid_t clock, int (*lock_function)(pthread_rwlock_t* __rwlock, const timespec* __timeout)) { RwlockWakeupHelperArg wakeup_arg; @@ -1134,6 +1204,38 @@ TEST(pthread, pthread_rwlock_timedwrlock_monotonic_np_timeout) { #endif // __BIONIC__ } +TEST(pthread, pthread_rwlock_clockwrlock_monotonic_timeout) { +#if defined(__BIONIC__) + pthread_rwlock_timedwrlock_timeout_helper( + CLOCK_MONOTONIC, [](pthread_rwlock_t* __rwlock, const timespec* __timeout) { + return pthread_rwlock_clockwrlock(__rwlock, CLOCK_MONOTONIC, __timeout); + }); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_rwlock_clockwrlock not available"; +#endif // __BIONIC__ +} + +TEST(pthread, pthread_rwlock_clockwrlock_realtime_timeout) { +#if defined(__BIONIC__) + pthread_rwlock_timedwrlock_timeout_helper( + CLOCK_REALTIME, [](pthread_rwlock_t* __rwlock, const timespec* __timeout) { + return pthread_rwlock_clockwrlock(__rwlock, CLOCK_REALTIME, __timeout); + }); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_rwlock_clockwrlock not available"; +#endif // __BIONIC__ +} + +TEST(pthread, pthread_rwlock_clockwrlock_invalid) { +#if defined(__BIONIC__) + pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER; + timespec ts; + EXPECT_EQ(EINVAL, pthread_rwlock_clockwrlock(&lock, CLOCK_PROCESS_CPUTIME_ID, &ts)); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_rwlock_clockrwlock not available"; +#endif // __BIONIC__ +} + class RwlockKindTestHelper { private: struct ThreadArg { @@ -1392,16 +1494,43 @@ class pthread_CondWakeupTest : public ::testing::Test { ASSERT_EQ(0, pthread_condattr_destroy(&attr)); } - void StartWaitingThread(std::function<int (pthread_cond_t* cond, pthread_mutex_t* mutex)> wait_function) { + void StartWaitingThread( + std::function<int(pthread_cond_t* cond, pthread_mutex_t* mutex)> wait_function) { progress = INITIALIZED; this->wait_function = wait_function; - ASSERT_EQ(0, pthread_create(&thread, nullptr, reinterpret_cast<void* (*)(void*)>(WaitThreadFn), this)); + ASSERT_EQ(0, pthread_create(&thread, nullptr, reinterpret_cast<void* (*)(void*)>(WaitThreadFn), + this)); while (progress != WAITING) { usleep(5000); } usleep(5000); } + void RunTimedTest( + clockid_t clock, + std::function<int(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* timeout)> + wait_function) { + timespec ts; + ASSERT_EQ(0, clock_gettime(clock, &ts)); + ts.tv_sec += 1; + + StartWaitingThread([&wait_function, &ts](pthread_cond_t* cond, pthread_mutex_t* mutex) { + return wait_function(cond, mutex, &ts); + }); + + progress = SIGNALED; + ASSERT_EQ(0, pthread_cond_signal(&cond)); + } + + void RunTimedTest(clockid_t clock, std::function<int(pthread_cond_t* cond, pthread_mutex_t* mutex, + clockid_t clock, const timespec* timeout)> + wait_function) { + RunTimedTest(clock, [clock, &wait_function](pthread_cond_t* cond, pthread_mutex_t* mutex, + const timespec* timeout) { + return wait_function(cond, mutex, clock, timeout); + }); + } + void TearDown() override { ASSERT_EQ(0, pthread_join(thread, nullptr)); ASSERT_EQ(FINISHED, progress); @@ -1442,52 +1571,80 @@ TEST_F(pthread_CondWakeupTest, broadcast_wait) { TEST_F(pthread_CondWakeupTest, signal_timedwait_CLOCK_REALTIME) { InitCond(CLOCK_REALTIME); - timespec ts; - ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts)); - ts.tv_sec += 1; - StartWaitingThread([&](pthread_cond_t* cond, pthread_mutex_t* mutex) { - return pthread_cond_timedwait(cond, mutex, &ts); - }); - progress = SIGNALED; - ASSERT_EQ(0, pthread_cond_signal(&cond)); + RunTimedTest(CLOCK_REALTIME, pthread_cond_timedwait); } TEST_F(pthread_CondWakeupTest, signal_timedwait_CLOCK_MONOTONIC) { InitCond(CLOCK_MONOTONIC); - timespec ts; - ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts)); - ts.tv_sec += 1; - StartWaitingThread([&](pthread_cond_t* cond, pthread_mutex_t* mutex) { - return pthread_cond_timedwait(cond, mutex, &ts); - }); - progress = SIGNALED; - ASSERT_EQ(0, pthread_cond_signal(&cond)); + RunTimedTest(CLOCK_MONOTONIC, pthread_cond_timedwait); } TEST_F(pthread_CondWakeupTest, signal_timedwait_CLOCK_MONOTONIC_np) { #if defined(__BIONIC__) InitCond(CLOCK_REALTIME); - timespec ts; - ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts)); - ts.tv_sec += 1; - StartWaitingThread([&](pthread_cond_t* cond, pthread_mutex_t* mutex) { - return pthread_cond_timedwait_monotonic_np(cond, mutex, &ts); - }); - progress = SIGNALED; - ASSERT_EQ(0, pthread_cond_signal(&cond)); + RunTimedTest(CLOCK_MONOTONIC, pthread_cond_timedwait_monotonic_np); #else // __BIONIC__ GTEST_SKIP() << "pthread_cond_timedwait_monotonic_np not available"; #endif // __BIONIC__ } -static void pthread_cond_timedwait_timeout_helper(clockid_t clock, +TEST_F(pthread_CondWakeupTest, signal_clockwait_monotonic_monotonic) { +#if defined(__BIONIC__) + InitCond(CLOCK_MONOTONIC); + RunTimedTest(CLOCK_MONOTONIC, pthread_cond_clockwait); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_cond_clockwait not available"; +#endif // __BIONIC__ +} + +TEST_F(pthread_CondWakeupTest, signal_clockwait_monotonic_realtime) { +#if defined(__BIONIC__) + InitCond(CLOCK_MONOTONIC); + RunTimedTest(CLOCK_REALTIME, pthread_cond_clockwait); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_cond_clockwait not available"; +#endif // __BIONIC__ +} + +TEST_F(pthread_CondWakeupTest, signal_clockwait_realtime_monotonic) { +#if defined(__BIONIC__) + InitCond(CLOCK_REALTIME); + RunTimedTest(CLOCK_MONOTONIC, pthread_cond_clockwait); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_cond_clockwait not available"; +#endif // __BIONIC__ +} + +TEST_F(pthread_CondWakeupTest, signal_clockwait_realtime_realtime) { +#if defined(__BIONIC__) + InitCond(CLOCK_REALTIME); + RunTimedTest(CLOCK_REALTIME, pthread_cond_clockwait); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_cond_clockwait not available"; +#endif // __BIONIC__ +} + +static void pthread_cond_timedwait_timeout_helper(bool init_monotonic, clockid_t clock, int (*wait_function)(pthread_cond_t* __cond, pthread_mutex_t* __mutex, const timespec* __timeout)) { pthread_mutex_t mutex; ASSERT_EQ(0, pthread_mutex_init(&mutex, nullptr)); pthread_cond_t cond; - ASSERT_EQ(0, pthread_cond_init(&cond, nullptr)); + + if (init_monotonic) { + pthread_condattr_t attr; + pthread_condattr_init(&attr); + + ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)); + clockid_t clock; + ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock)); + ASSERT_EQ(CLOCK_MONOTONIC, clock); + + ASSERT_EQ(0, pthread_cond_init(&cond, &attr)); + } else { + ASSERT_EQ(0, pthread_cond_init(&cond, nullptr)); + } ASSERT_EQ(0, pthread_mutex_lock(&mutex)); timespec ts; @@ -1504,17 +1661,57 @@ static void pthread_cond_timedwait_timeout_helper(clockid_t clock, } TEST(pthread, pthread_cond_timedwait_timeout) { - pthread_cond_timedwait_timeout_helper(CLOCK_REALTIME, pthread_cond_timedwait); + pthread_cond_timedwait_timeout_helper(false, CLOCK_REALTIME, pthread_cond_timedwait); } TEST(pthread, pthread_cond_timedwait_monotonic_np_timeout) { #if defined(__BIONIC__) - pthread_cond_timedwait_timeout_helper(CLOCK_MONOTONIC, pthread_cond_timedwait_monotonic_np); + pthread_cond_timedwait_timeout_helper(false, CLOCK_MONOTONIC, pthread_cond_timedwait_monotonic_np); + pthread_cond_timedwait_timeout_helper(true, CLOCK_MONOTONIC, pthread_cond_timedwait_monotonic_np); #else // __BIONIC__ GTEST_SKIP() << "pthread_cond_timedwait_monotonic_np not available"; #endif // __BIONIC__ } +TEST(pthread, pthread_cond_clockwait_timeout) { +#if defined(__BIONIC__) + pthread_cond_timedwait_timeout_helper( + false, CLOCK_MONOTONIC, + [](pthread_cond_t* __cond, pthread_mutex_t* __mutex, const timespec* __timeout) { + return pthread_cond_clockwait(__cond, __mutex, CLOCK_MONOTONIC, __timeout); + }); + pthread_cond_timedwait_timeout_helper( + true, CLOCK_MONOTONIC, + [](pthread_cond_t* __cond, pthread_mutex_t* __mutex, const timespec* __timeout) { + return pthread_cond_clockwait(__cond, __mutex, CLOCK_MONOTONIC, __timeout); + }); + pthread_cond_timedwait_timeout_helper( + false, CLOCK_REALTIME, + [](pthread_cond_t* __cond, pthread_mutex_t* __mutex, const timespec* __timeout) { + return pthread_cond_clockwait(__cond, __mutex, CLOCK_REALTIME, __timeout); + }); + pthread_cond_timedwait_timeout_helper( + true, CLOCK_REALTIME, + [](pthread_cond_t* __cond, pthread_mutex_t* __mutex, const timespec* __timeout) { + return pthread_cond_clockwait(__cond, __mutex, CLOCK_REALTIME, __timeout); + }); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_cond_clockwait not available"; +#endif // __BIONIC__ +} + +TEST(pthread, pthread_cond_clockwait_invalid) { +#if defined(__BIONIC__) + pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + timespec ts; + EXPECT_EQ(EINVAL, pthread_cond_clockwait(&cond, &mutex, CLOCK_PROCESS_CPUTIME_ID, &ts)); + +#else // __BIONIC__ + GTEST_SKIP() << "pthread_cond_clockwait not available"; +#endif // __BIONIC__ +} + TEST(pthread, pthread_attr_getstack__main_thread) { // This test is only meaningful for the main thread, so make sure we're running on it! ASSERT_EQ(getpid(), syscall(__NR_gettid)); @@ -2180,6 +2377,21 @@ TEST(pthread, pthread_mutex_timedlock_monotonic_np) { #endif // __BIONIC__ } +TEST(pthread, pthread_mutex_clocklock) { +#if defined(__BIONIC__) + pthread_mutex_timedlock_helper( + CLOCK_MONOTONIC, [](pthread_mutex_t* __mutex, const timespec* __timeout) { + return pthread_mutex_clocklock(__mutex, CLOCK_MONOTONIC, __timeout); + }); + pthread_mutex_timedlock_helper( + CLOCK_REALTIME, [](pthread_mutex_t* __mutex, const timespec* __timeout) { + return pthread_mutex_clocklock(__mutex, CLOCK_REALTIME, __timeout); + }); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_mutex_clocklock not available"; +#endif // __BIONIC__ +} + static void pthread_mutex_timedlock_pi_helper(clockid_t clock, int (*lock_function)(pthread_mutex_t* __mutex, const timespec* __timeout)) { @@ -2231,6 +2443,31 @@ TEST(pthread, pthread_mutex_timedlock_monotonic_np_pi) { #endif // __BIONIC__ } +TEST(pthread, pthread_mutex_clocklock_pi) { +#if defined(__BIONIC__) + pthread_mutex_timedlock_pi_helper( + CLOCK_MONOTONIC, [](pthread_mutex_t* __mutex, const timespec* __timeout) { + return pthread_mutex_clocklock(__mutex, CLOCK_MONOTONIC, __timeout); + }); + pthread_mutex_timedlock_pi_helper( + CLOCK_REALTIME, [](pthread_mutex_t* __mutex, const timespec* __timeout) { + return pthread_mutex_clocklock(__mutex, CLOCK_REALTIME, __timeout); + }); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_mutex_clocklock not available"; +#endif // __BIONIC__ +} + +TEST(pthread, pthread_mutex_clocklock_invalid) { +#if defined(__BIONIC__) + pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + timespec ts; + EXPECT_EQ(EINVAL, pthread_mutex_clocklock(&mutex, CLOCK_PROCESS_CPUTIME_ID, &ts)); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_mutex_clocklock not available"; +#endif // __BIONIC__ +} + TEST(pthread, pthread_mutex_using_destroyed_mutex) { #if defined(__BIONIC__) pthread_mutex_t m; @@ -2247,6 +2484,13 @@ TEST(pthread, pthread_mutex_using_destroyed_mutex) { "pthread_mutex_timedlock called on a destroyed mutex"); ASSERT_EXIT(pthread_mutex_timedlock_monotonic_np(&m, &ts), ::testing::KilledBySignal(SIGABRT), "pthread_mutex_timedlock_monotonic_np called on a destroyed mutex"); + ASSERT_EXIT(pthread_mutex_clocklock(&m, CLOCK_MONOTONIC, &ts), ::testing::KilledBySignal(SIGABRT), + "pthread_mutex_clocklock called on a destroyed mutex"); + ASSERT_EXIT(pthread_mutex_clocklock(&m, CLOCK_REALTIME, &ts), ::testing::KilledBySignal(SIGABRT), + "pthread_mutex_clocklock called on a destroyed mutex"); + ASSERT_EXIT(pthread_mutex_clocklock(&m, CLOCK_PROCESS_CPUTIME_ID, &ts), + ::testing::KilledBySignal(SIGABRT), + "pthread_mutex_clocklock called on a destroyed mutex"); ASSERT_EXIT(pthread_mutex_destroy(&m), ::testing::KilledBySignal(SIGABRT), "pthread_mutex_destroy called on a destroyed mutex"); #else |