blob: ee0b1beba9936a60023bfa35c05b15b236cb937c [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080016
17#include "mutex.h"
18
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080019#include "common_runtime_test.h"
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080020
21namespace art {
22
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080023class MutexTest : public CommonRuntimeTest {};
Brian Carlstrom92c9a352012-06-21 18:21:59 -070024
Elliott Hughes3efb8412012-03-16 16:09:38 -070025struct MutexTester {
26 static void AssertDepth(Mutex& mu, uint32_t expected_depth) {
27 ASSERT_EQ(expected_depth, mu.GetDepth());
Elliott Hughesf1498432012-03-28 19:34:27 -070028
29 // This test is single-threaded, so we also know _who_ should hold the lock.
30 if (expected_depth == 0) {
Ian Rogers81d425b2012-09-27 16:03:43 -070031 mu.AssertNotHeld(Thread::Current());
Elliott Hughesf1498432012-03-28 19:34:27 -070032 } else {
Ian Rogers81d425b2012-09-27 16:03:43 -070033 mu.AssertHeld(Thread::Current());
Elliott Hughesf1498432012-03-28 19:34:27 -070034 }
Elliott Hughes3efb8412012-03-16 16:09:38 -070035 }
36};
37
Brian Carlstrom92c9a352012-06-21 18:21:59 -070038TEST_F(MutexTest, LockUnlock) {
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080039 Mutex mu("test mutex");
Elliott Hughes3efb8412012-03-16 16:09:38 -070040 MutexTester::AssertDepth(mu, 0U);
Ian Rogers81d425b2012-09-27 16:03:43 -070041 mu.Lock(Thread::Current());
Elliott Hughes3efb8412012-03-16 16:09:38 -070042 MutexTester::AssertDepth(mu, 1U);
Ian Rogers81d425b2012-09-27 16:03:43 -070043 mu.Unlock(Thread::Current());
Elliott Hughes3efb8412012-03-16 16:09:38 -070044 MutexTester::AssertDepth(mu, 0U);
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080045}
46
Elliott Hughes72d63d42012-06-18 16:51:20 -070047// GCC has trouble with our mutex tests, so we have to turn off thread safety analysis.
Elliott Hughes81414052012-06-18 16:43:50 -070048static void TryLockUnlockTest() NO_THREAD_SAFETY_ANALYSIS {
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080049 Mutex mu("test mutex");
Elliott Hughes3efb8412012-03-16 16:09:38 -070050 MutexTester::AssertDepth(mu, 0U);
Ian Rogers81d425b2012-09-27 16:03:43 -070051 ASSERT_TRUE(mu.TryLock(Thread::Current()));
Elliott Hughes81414052012-06-18 16:43:50 -070052 MutexTester::AssertDepth(mu, 1U);
Ian Rogers81d425b2012-09-27 16:03:43 -070053 mu.Unlock(Thread::Current());
Elliott Hughes81414052012-06-18 16:43:50 -070054 MutexTester::AssertDepth(mu, 0U);
55}
56
Brian Carlstrom92c9a352012-06-21 18:21:59 -070057TEST_F(MutexTest, TryLockUnlock) {
Elliott Hughes81414052012-06-18 16:43:50 -070058 TryLockUnlockTest();
Elliott Hughesf8349362012-06-18 15:00:06 -070059}
60
Elliott Hughes72d63d42012-06-18 16:51:20 -070061// GCC has trouble with our mutex tests, so we have to turn off thread safety analysis.
Elliott Hughesf8349362012-06-18 15:00:06 -070062static void RecursiveLockUnlockTest() NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers00f7d0e2012-07-19 15:28:27 -070063 Mutex mu("test mutex", kDefaultMutexLevel, true);
Elliott Hughesf8349362012-06-18 15:00:06 -070064 MutexTester::AssertDepth(mu, 0U);
Ian Rogers81d425b2012-09-27 16:03:43 -070065 mu.Lock(Thread::Current());
Elliott Hughesf8349362012-06-18 15:00:06 -070066 MutexTester::AssertDepth(mu, 1U);
Ian Rogers81d425b2012-09-27 16:03:43 -070067 mu.Lock(Thread::Current());
Elliott Hughesf8349362012-06-18 15:00:06 -070068 MutexTester::AssertDepth(mu, 2U);
Ian Rogers81d425b2012-09-27 16:03:43 -070069 mu.Unlock(Thread::Current());
Elliott Hughes3efb8412012-03-16 16:09:38 -070070 MutexTester::AssertDepth(mu, 1U);
Ian Rogers81d425b2012-09-27 16:03:43 -070071 mu.Unlock(Thread::Current());
Elliott Hughes3efb8412012-03-16 16:09:38 -070072 MutexTester::AssertDepth(mu, 0U);
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080073}
74
Brian Carlstrom92c9a352012-06-21 18:21:59 -070075TEST_F(MutexTest, RecursiveLockUnlock) {
Elliott Hughesf8349362012-06-18 15:00:06 -070076 RecursiveLockUnlockTest();
77}
78
Elliott Hughes72d63d42012-06-18 16:51:20 -070079// GCC has trouble with our mutex tests, so we have to turn off thread safety analysis.
Elliott Hughesf8349362012-06-18 15:00:06 -070080static void RecursiveTryLockUnlockTest() NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers00f7d0e2012-07-19 15:28:27 -070081 Mutex mu("test mutex", kDefaultMutexLevel, true);
Elliott Hughes3efb8412012-03-16 16:09:38 -070082 MutexTester::AssertDepth(mu, 0U);
Ian Rogers81d425b2012-09-27 16:03:43 -070083 ASSERT_TRUE(mu.TryLock(Thread::Current()));
Elliott Hughes3efb8412012-03-16 16:09:38 -070084 MutexTester::AssertDepth(mu, 1U);
Ian Rogers81d425b2012-09-27 16:03:43 -070085 ASSERT_TRUE(mu.TryLock(Thread::Current()));
Elliott Hughes3efb8412012-03-16 16:09:38 -070086 MutexTester::AssertDepth(mu, 2U);
Ian Rogers81d425b2012-09-27 16:03:43 -070087 mu.Unlock(Thread::Current());
Elliott Hughes3efb8412012-03-16 16:09:38 -070088 MutexTester::AssertDepth(mu, 1U);
Ian Rogers81d425b2012-09-27 16:03:43 -070089 mu.Unlock(Thread::Current());
Elliott Hughes3efb8412012-03-16 16:09:38 -070090 MutexTester::AssertDepth(mu, 0U);
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080091}
92
Brian Carlstrom92c9a352012-06-21 18:21:59 -070093TEST_F(MutexTest, RecursiveTryLockUnlock) {
Elliott Hughesf8349362012-06-18 15:00:06 -070094 RecursiveTryLockUnlockTest();
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080095}
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080096
Brian Carlstrom92c9a352012-06-21 18:21:59 -070097
98struct RecursiveLockWait {
Ian Rogers00f7d0e2012-07-19 15:28:27 -070099 explicit RecursiveLockWait()
Ian Rogersc604d732012-10-14 16:09:54 -0700100 : mu("test mutex", kDefaultMutexLevel, true), cv("test condition variable", mu) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700101 }
Brian Carlstrom92c9a352012-06-21 18:21:59 -0700102
103 static void* Callback(void* arg) {
104 RecursiveLockWait* state = reinterpret_cast<RecursiveLockWait*>(arg);
Ian Rogers81d425b2012-09-27 16:03:43 -0700105 state->mu.Lock(Thread::Current());
Ian Rogersc604d732012-10-14 16:09:54 -0700106 state->cv.Signal(Thread::Current());
Ian Rogers81d425b2012-09-27 16:03:43 -0700107 state->mu.Unlock(Thread::Current());
Brian Carlstrom92c9a352012-06-21 18:21:59 -0700108 return NULL;
109 }
110
111 Mutex mu;
112 ConditionVariable cv;
113};
114
115// GCC has trouble with our mutex tests, so we have to turn off thread safety analysis.
116static void RecursiveLockWaitTest() NO_THREAD_SAFETY_ANALYSIS {
117 RecursiveLockWait state;
Ian Rogers81d425b2012-09-27 16:03:43 -0700118 state.mu.Lock(Thread::Current());
119 state.mu.Lock(Thread::Current());
Brian Carlstrom92c9a352012-06-21 18:21:59 -0700120
121 pthread_t pthread;
122 int pthread_create_result = pthread_create(&pthread, NULL, RecursiveLockWait::Callback, &state);
123 ASSERT_EQ(0, pthread_create_result);
124
Ian Rogersc604d732012-10-14 16:09:54 -0700125 state.cv.Wait(Thread::Current());
Brian Carlstrom92c9a352012-06-21 18:21:59 -0700126
Ian Rogers81d425b2012-09-27 16:03:43 -0700127 state.mu.Unlock(Thread::Current());
128 state.mu.Unlock(Thread::Current());
Ian Rogers23055dc2013-04-18 16:29:16 -0700129 EXPECT_EQ(pthread_join(pthread, NULL), 0);
Brian Carlstrom92c9a352012-06-21 18:21:59 -0700130}
131
132// This ensures we don't hang when waiting on a recursively locked mutex,
133// which is not supported with bare pthread_mutex_t.
134TEST_F(MutexTest, RecursiveLockWait) {
135 RecursiveLockWaitTest();
136}
137
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700138TEST_F(MutexTest, SharedLockUnlock) {
139 ReaderWriterMutex mu("test rwmutex");
Ian Rogers81d425b2012-09-27 16:03:43 -0700140 mu.AssertNotHeld(Thread::Current());
141 mu.AssertNotExclusiveHeld(Thread::Current());
142 mu.SharedLock(Thread::Current());
143 mu.AssertSharedHeld(Thread::Current());
144 mu.AssertNotExclusiveHeld(Thread::Current());
145 mu.SharedUnlock(Thread::Current());
146 mu.AssertNotHeld(Thread::Current());
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700147}
148
149TEST_F(MutexTest, ExclusiveLockUnlock) {
150 ReaderWriterMutex mu("test rwmutex");
Ian Rogers81d425b2012-09-27 16:03:43 -0700151 mu.AssertNotHeld(Thread::Current());
152 mu.ExclusiveLock(Thread::Current());
153 mu.AssertSharedHeld(Thread::Current());
154 mu.AssertExclusiveHeld(Thread::Current());
155 mu.ExclusiveUnlock(Thread::Current());
156 mu.AssertNotHeld(Thread::Current());
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700157}
158
159// GCC has trouble with our mutex tests, so we have to turn off thread safety analysis.
160static void SharedTryLockUnlockTest() NO_THREAD_SAFETY_ANALYSIS {
161 ReaderWriterMutex mu("test rwmutex");
Ian Rogers81d425b2012-09-27 16:03:43 -0700162 mu.AssertNotHeld(Thread::Current());
163 ASSERT_TRUE(mu.SharedTryLock(Thread::Current()));
164 mu.AssertSharedHeld(Thread::Current());
165 mu.SharedUnlock(Thread::Current());
166 mu.AssertNotHeld(Thread::Current());
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700167}
168
169TEST_F(MutexTest, SharedTryLockUnlock) {
170 SharedTryLockUnlockTest();
171}
172
Brian Carlstromcd74c4b2012-01-23 13:21:00 -0800173} // namespace art