blob: 4dac3c606f3871c3a5c1232946016ef7973e8081 [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 Carlstrom92c9a352012-06-21 18:21:59 -070019#include "common_test.h"
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080020
21namespace art {
22
Brian Carlstrom92c9a352012-06-21 18:21:59 -070023class MutexTest : public CommonTest {};
24
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()
100 : mu("test mutex", kDefaultMutexLevel, true), cv("test condition variable") {
101 }
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());
Brian Carlstrom92c9a352012-06-21 18:21:59 -0700106 state->cv.Signal();
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 Rogers81d425b2012-09-27 16:03:43 -0700125 state.cv.Wait(Thread::Current(), state.mu);
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());
Brian Carlstrom92c9a352012-06-21 18:21:59 -0700129}
130
131// This ensures we don't hang when waiting on a recursively locked mutex,
132// which is not supported with bare pthread_mutex_t.
133TEST_F(MutexTest, RecursiveLockWait) {
134 RecursiveLockWaitTest();
135}
136
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700137TEST_F(MutexTest, SharedLockUnlock) {
138 ReaderWriterMutex mu("test rwmutex");
Ian Rogers81d425b2012-09-27 16:03:43 -0700139 mu.AssertNotHeld(Thread::Current());
140 mu.AssertNotExclusiveHeld(Thread::Current());
141 mu.SharedLock(Thread::Current());
142 mu.AssertSharedHeld(Thread::Current());
143 mu.AssertNotExclusiveHeld(Thread::Current());
144 mu.SharedUnlock(Thread::Current());
145 mu.AssertNotHeld(Thread::Current());
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700146}
147
148TEST_F(MutexTest, ExclusiveLockUnlock) {
149 ReaderWriterMutex mu("test rwmutex");
Ian Rogers81d425b2012-09-27 16:03:43 -0700150 mu.AssertNotHeld(Thread::Current());
151 mu.ExclusiveLock(Thread::Current());
152 mu.AssertSharedHeld(Thread::Current());
153 mu.AssertExclusiveHeld(Thread::Current());
154 mu.ExclusiveUnlock(Thread::Current());
155 mu.AssertNotHeld(Thread::Current());
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700156}
157
158// GCC has trouble with our mutex tests, so we have to turn off thread safety analysis.
159static void SharedTryLockUnlockTest() NO_THREAD_SAFETY_ANALYSIS {
160 ReaderWriterMutex mu("test rwmutex");
Ian Rogers81d425b2012-09-27 16:03:43 -0700161 mu.AssertNotHeld(Thread::Current());
162 ASSERT_TRUE(mu.SharedTryLock(Thread::Current()));
163 mu.AssertSharedHeld(Thread::Current());
164 mu.SharedUnlock(Thread::Current());
165 mu.AssertNotHeld(Thread::Current());
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700166}
167
168TEST_F(MutexTest, SharedTryLockUnlock) {
169 SharedTryLockUnlockTest();
170}
171
Brian Carlstromcd74c4b2012-01-23 13:21:00 -0800172} // namespace art