Support priority inheritance mutex in 32-bit programs.
Add fast path calling PIMutexTryLock() in pthread_mutex_lock.
Add trace for pi mutex waiting.
Bug: http://b/29177606
Test: run bionic-unit-tests.
Test: run bionic-benchmarks.
Change-Id: I30b6436692d5ea6b63ca9905df745edb843b5528
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 9ecb10c..40059d0 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -1730,15 +1730,42 @@
}
TEST(pthread, pthread_mutex_lock_pi) {
-#if defined(__BIONIC__) && !defined(__LP64__)
- GTEST_LOG_(INFO) << "PTHREAD_PRIO_INHERIT isn't supported in 32bit programs, skipping test";
- return;
-#endif
TestPthreadMutexLockNormal(PTHREAD_PRIO_INHERIT);
TestPthreadMutexLockErrorCheck(PTHREAD_PRIO_INHERIT);
TestPthreadMutexLockRecursive(PTHREAD_PRIO_INHERIT);
}
+TEST(pthread, pthread_mutex_pi_count_limit) {
+#if defined(__BIONIC__) && !defined(__LP64__)
+ // Bionic only supports 65536 pi mutexes in 32-bit programs.
+ pthread_mutexattr_t attr;
+ ASSERT_EQ(0, pthread_mutexattr_init(&attr));
+ ASSERT_EQ(0, pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT));
+ std::vector<pthread_mutex_t> mutexes(65536);
+ // Test if we can use 65536 pi mutexes at the same time.
+ // Run 2 times to check if freed pi mutexes can be recycled.
+ for (int repeat = 0; repeat < 2; ++repeat) {
+ for (auto& m : mutexes) {
+ ASSERT_EQ(0, pthread_mutex_init(&m, &attr));
+ }
+ pthread_mutex_t m;
+ ASSERT_EQ(ENOMEM, pthread_mutex_init(&m, &attr));
+ for (auto& m : mutexes) {
+ ASSERT_EQ(0, pthread_mutex_lock(&m));
+ }
+ for (auto& m : mutexes) {
+ ASSERT_EQ(0, pthread_mutex_unlock(&m));
+ }
+ for (auto& m : mutexes) {
+ ASSERT_EQ(0, pthread_mutex_destroy(&m));
+ }
+ }
+ ASSERT_EQ(0, pthread_mutexattr_destroy(&attr));
+#else
+ GTEST_LOG_(INFO) << "This test does nothing as pi mutex count isn't limited.\n";
+#endif
+}
+
TEST(pthread, pthread_mutex_init_same_as_static_initializers) {
pthread_mutex_t lock_normal = PTHREAD_MUTEX_INITIALIZER;
PthreadMutex m1(PTHREAD_MUTEX_NORMAL);
@@ -1755,6 +1782,7 @@
ASSERT_EQ(0, memcmp(&lock_recursive, &m3.lock, sizeof(pthread_mutex_t)));
ASSERT_EQ(0, pthread_mutex_destroy(&lock_recursive));
}
+
class MutexWakeupHelper {
private:
PthreadMutex m;
@@ -1903,10 +1931,6 @@
};
TEST(pthread, pthread_mutex_pi_wakeup) {
-#if defined(__BIONIC__) && !defined(__LP64__)
- GTEST_LOG_(INFO) << "PTHREAD_PRIO_INHERIT isn't supported in 32bit programs, skipping test";
- return;
-#endif
for (int type : {PTHREAD_MUTEX_NORMAL, PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_ERRORCHECK}) {
for (int protocol : {PTHREAD_PRIO_INHERIT}) {
PIMutexWakeupHelper helper(type, protocol);
@@ -1959,10 +1983,6 @@
}
TEST(pthread, pthread_mutex_timedlock_pi) {
-#if defined(__BIONIC__) && !defined(__LP64__)
- GTEST_LOG_(INFO) << "PTHREAD_PRIO_INHERIT isn't supported in 32bit programs, skipping test";
- return;
-#endif
PthreadMutex m(PTHREAD_MUTEX_NORMAL, PTHREAD_PRIO_INHERIT);
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);