summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2015-02-11 17:04:36 -0800
committerYabin Cui <yabinc@google.com>2015-03-04 18:16:20 -0800
commit08ee8d2030fbc73c4c144e819dd68806b0351cbe (patch)
tree61c0f1027bd8967ff7eb8e95a128ee10e260ca32 /tests
parentee17e8800418a74e21dba11658234363cf6f6032 (diff)
downloadbionic-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.cpp75
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;