diff options
author | Yabin Cui <yabinc@google.com> | 2015-02-11 17:04:36 -0800 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2015-03-04 18:16:20 -0800 |
commit | 08ee8d2030fbc73c4c144e819dd68806b0351cbe (patch) | |
tree | 61c0f1027bd8967ff7eb8e95a128ee10e260ca32 /tests | |
parent | ee17e8800418a74e21dba11658234363cf6f6032 (diff) | |
download | bionic-08ee8d2030fbc73c4c144e819dd68806b0351cbe.zip bionic-08ee8d2030fbc73c4c144e819dd68806b0351cbe.tar.gz bionic-08ee8d2030fbc73c4c144e819dd68806b0351cbe.tar.bz2 |
Switch pthread_rwlock_t to stdatomic.
Bug: 19099838
Change-Id: Ie82967a60b5cec61a8bdd1e0e4a03738d01944f8
Diffstat (limited to 'tests')
-rw-r--r-- | tests/pthread_test.cpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp index 5dc60ee..c507faa 100644 --- a/tests/pthread_test.cpp +++ b/tests/pthread_test.cpp @@ -33,6 +33,8 @@ #include <time.h> #include <unistd.h> +#include <atomic> + TEST(pthread, pthread_key_create) { pthread_key_t key; ASSERT_EQ(0, pthread_key_create(&key, NULL)); @@ -699,6 +701,79 @@ TEST(pthread, pthread_rwlock_smoke) { ASSERT_EQ(0, pthread_rwlock_destroy(&l)); } +struct RwlockWakeupHelperArg { + pthread_rwlock_t lock; + enum Progress { + LOCK_INITIALIZED, + LOCK_WAITING, + LOCK_RELEASED, + LOCK_ACCESSED + }; + std::atomic<Progress> progress; +}; + +static void pthread_rwlock_reader_wakeup_writer_helper(RwlockWakeupHelperArg* arg) { + ASSERT_EQ(RwlockWakeupHelperArg::LOCK_INITIALIZED, arg->progress); + arg->progress = RwlockWakeupHelperArg::LOCK_WAITING; + + ASSERT_EQ(EBUSY, pthread_rwlock_trywrlock(&arg->lock)); + ASSERT_EQ(0, pthread_rwlock_wrlock(&arg->lock)); + ASSERT_EQ(RwlockWakeupHelperArg::LOCK_RELEASED, arg->progress); + ASSERT_EQ(0, pthread_rwlock_unlock(&arg->lock)); + + arg->progress = RwlockWakeupHelperArg::LOCK_ACCESSED; +} + +TEST(pthread, pthread_rwlock_reader_wakeup_writer) { + RwlockWakeupHelperArg wakeup_arg; + ASSERT_EQ(0, pthread_rwlock_init(&wakeup_arg.lock, NULL)); + ASSERT_EQ(0, pthread_rwlock_rdlock(&wakeup_arg.lock)); + wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_INITIALIZED; + + pthread_t thread; + ASSERT_EQ(0, pthread_create(&thread, NULL, + reinterpret_cast<void* (*)(void*)>(pthread_rwlock_reader_wakeup_writer_helper), &wakeup_arg)); + sleep(1); + ASSERT_EQ(RwlockWakeupHelperArg::LOCK_WAITING, wakeup_arg.progress); + wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_RELEASED; + ASSERT_EQ(0, pthread_rwlock_unlock(&wakeup_arg.lock)); + + ASSERT_EQ(0, pthread_join(thread, NULL)); + ASSERT_EQ(RwlockWakeupHelperArg::LOCK_ACCESSED, wakeup_arg.progress); + ASSERT_EQ(0, pthread_rwlock_destroy(&wakeup_arg.lock)); +} + +static void pthread_rwlock_writer_wakeup_reader_helper(RwlockWakeupHelperArg* arg) { + ASSERT_EQ(RwlockWakeupHelperArg::LOCK_INITIALIZED, arg->progress); + arg->progress = RwlockWakeupHelperArg::LOCK_WAITING; + + ASSERT_EQ(EBUSY, pthread_rwlock_tryrdlock(&arg->lock)); + ASSERT_EQ(0, pthread_rwlock_rdlock(&arg->lock)); + ASSERT_EQ(RwlockWakeupHelperArg::LOCK_RELEASED, arg->progress); + ASSERT_EQ(0, pthread_rwlock_unlock(&arg->lock)); + + arg->progress = RwlockWakeupHelperArg::LOCK_ACCESSED; +} + +TEST(pthread, pthread_rwlock_writer_wakeup_reader) { + RwlockWakeupHelperArg wakeup_arg; + ASSERT_EQ(0, pthread_rwlock_init(&wakeup_arg.lock, NULL)); + ASSERT_EQ(0, pthread_rwlock_wrlock(&wakeup_arg.lock)); + wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_INITIALIZED; + + pthread_t thread; + ASSERT_EQ(0, pthread_create(&thread, NULL, + reinterpret_cast<void* (*)(void*)>(pthread_rwlock_writer_wakeup_reader_helper), &wakeup_arg)); + sleep(1); + ASSERT_EQ(RwlockWakeupHelperArg::LOCK_WAITING, wakeup_arg.progress); + wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_RELEASED; + ASSERT_EQ(0, pthread_rwlock_unlock(&wakeup_arg.lock)); + + ASSERT_EQ(0, pthread_join(thread, NULL)); + ASSERT_EQ(RwlockWakeupHelperArg::LOCK_ACCESSED, wakeup_arg.progress); + ASSERT_EQ(0, pthread_rwlock_destroy(&wakeup_arg.lock)); +} + static int g_once_fn_call_count = 0; static void OnceFn() { ++g_once_fn_call_count; |