blob: 289d3ef8c13e9ca24f41fdaa469c73d1cda88c51 [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"
Ian Rogerse63db272014-07-15 15:36:11 -070020#include "thread-inl.h"
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080021
22namespace art {
23
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080024class MutexTest : public CommonRuntimeTest {};
Brian Carlstrom92c9a352012-06-21 18:21:59 -070025
Elliott Hughes3efb8412012-03-16 16:09:38 -070026struct MutexTester {
27 static void AssertDepth(Mutex& mu, uint32_t expected_depth) {
28 ASSERT_EQ(expected_depth, mu.GetDepth());
Elliott Hughesf1498432012-03-28 19:34:27 -070029
30 // This test is single-threaded, so we also know _who_ should hold the lock.
31 if (expected_depth == 0) {
Ian Rogers81d425b2012-09-27 16:03:43 -070032 mu.AssertNotHeld(Thread::Current());
Elliott Hughesf1498432012-03-28 19:34:27 -070033 } else {
Ian Rogers81d425b2012-09-27 16:03:43 -070034 mu.AssertHeld(Thread::Current());
Elliott Hughesf1498432012-03-28 19:34:27 -070035 }
Elliott Hughes3efb8412012-03-16 16:09:38 -070036 }
37};
38
Brian Carlstrom92c9a352012-06-21 18:21:59 -070039TEST_F(MutexTest, LockUnlock) {
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080040 Mutex mu("test mutex");
Elliott Hughes3efb8412012-03-16 16:09:38 -070041 MutexTester::AssertDepth(mu, 0U);
Ian Rogers81d425b2012-09-27 16:03:43 -070042 mu.Lock(Thread::Current());
Elliott Hughes3efb8412012-03-16 16:09:38 -070043 MutexTester::AssertDepth(mu, 1U);
Ian Rogers81d425b2012-09-27 16:03:43 -070044 mu.Unlock(Thread::Current());
Elliott Hughes3efb8412012-03-16 16:09:38 -070045 MutexTester::AssertDepth(mu, 0U);
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080046}
47
Elliott Hughes72d63d42012-06-18 16:51:20 -070048// GCC has trouble with our mutex tests, so we have to turn off thread safety analysis.
Elliott Hughes81414052012-06-18 16:43:50 -070049static void TryLockUnlockTest() NO_THREAD_SAFETY_ANALYSIS {
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080050 Mutex mu("test mutex");
Elliott Hughes3efb8412012-03-16 16:09:38 -070051 MutexTester::AssertDepth(mu, 0U);
Ian Rogers81d425b2012-09-27 16:03:43 -070052 ASSERT_TRUE(mu.TryLock(Thread::Current()));
Elliott Hughes81414052012-06-18 16:43:50 -070053 MutexTester::AssertDepth(mu, 1U);
Ian Rogers81d425b2012-09-27 16:03:43 -070054 mu.Unlock(Thread::Current());
Elliott Hughes81414052012-06-18 16:43:50 -070055 MutexTester::AssertDepth(mu, 0U);
56}
57
Brian Carlstrom92c9a352012-06-21 18:21:59 -070058TEST_F(MutexTest, TryLockUnlock) {
Elliott Hughes81414052012-06-18 16:43:50 -070059 TryLockUnlockTest();
Elliott Hughesf8349362012-06-18 15:00:06 -070060}
61
Elliott Hughes72d63d42012-06-18 16:51:20 -070062// GCC has trouble with our mutex tests, so we have to turn off thread safety analysis.
Elliott Hughesf8349362012-06-18 15:00:06 -070063static void RecursiveLockUnlockTest() NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers00f7d0e2012-07-19 15:28:27 -070064 Mutex mu("test mutex", kDefaultMutexLevel, true);
Elliott Hughesf8349362012-06-18 15:00:06 -070065 MutexTester::AssertDepth(mu, 0U);
Ian Rogers81d425b2012-09-27 16:03:43 -070066 mu.Lock(Thread::Current());
Elliott Hughesf8349362012-06-18 15:00:06 -070067 MutexTester::AssertDepth(mu, 1U);
Ian Rogers81d425b2012-09-27 16:03:43 -070068 mu.Lock(Thread::Current());
Elliott Hughesf8349362012-06-18 15:00:06 -070069 MutexTester::AssertDepth(mu, 2U);
Ian Rogers81d425b2012-09-27 16:03:43 -070070 mu.Unlock(Thread::Current());
Elliott Hughes3efb8412012-03-16 16:09:38 -070071 MutexTester::AssertDepth(mu, 1U);
Ian Rogers81d425b2012-09-27 16:03:43 -070072 mu.Unlock(Thread::Current());
Elliott Hughes3efb8412012-03-16 16:09:38 -070073 MutexTester::AssertDepth(mu, 0U);
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080074}
75
Brian Carlstrom92c9a352012-06-21 18:21:59 -070076TEST_F(MutexTest, RecursiveLockUnlock) {
Elliott Hughesf8349362012-06-18 15:00:06 -070077 RecursiveLockUnlockTest();
78}
79
Elliott Hughes72d63d42012-06-18 16:51:20 -070080// GCC has trouble with our mutex tests, so we have to turn off thread safety analysis.
Elliott Hughesf8349362012-06-18 15:00:06 -070081static void RecursiveTryLockUnlockTest() NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers00f7d0e2012-07-19 15:28:27 -070082 Mutex mu("test mutex", kDefaultMutexLevel, true);
Elliott Hughes3efb8412012-03-16 16:09:38 -070083 MutexTester::AssertDepth(mu, 0U);
Ian Rogers81d425b2012-09-27 16:03:43 -070084 ASSERT_TRUE(mu.TryLock(Thread::Current()));
Elliott Hughes3efb8412012-03-16 16:09:38 -070085 MutexTester::AssertDepth(mu, 1U);
Ian Rogers81d425b2012-09-27 16:03:43 -070086 ASSERT_TRUE(mu.TryLock(Thread::Current()));
Elliott Hughes3efb8412012-03-16 16:09:38 -070087 MutexTester::AssertDepth(mu, 2U);
Ian Rogers81d425b2012-09-27 16:03:43 -070088 mu.Unlock(Thread::Current());
Elliott Hughes3efb8412012-03-16 16:09:38 -070089 MutexTester::AssertDepth(mu, 1U);
Ian Rogers81d425b2012-09-27 16:03:43 -070090 mu.Unlock(Thread::Current());
Elliott Hughes3efb8412012-03-16 16:09:38 -070091 MutexTester::AssertDepth(mu, 0U);
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080092}
93
Brian Carlstrom92c9a352012-06-21 18:21:59 -070094TEST_F(MutexTest, RecursiveTryLockUnlock) {
Elliott Hughesf8349362012-06-18 15:00:06 -070095 RecursiveTryLockUnlockTest();
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080096}
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080097
Brian Carlstrom92c9a352012-06-21 18:21:59 -070098
99struct RecursiveLockWait {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700100 explicit RecursiveLockWait()
Ian Rogersc604d732012-10-14 16:09:54 -0700101 : mu("test mutex", kDefaultMutexLevel, true), cv("test condition variable", mu) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700102 }
Brian Carlstrom92c9a352012-06-21 18:21:59 -0700103
104 static void* Callback(void* arg) {
105 RecursiveLockWait* state = reinterpret_cast<RecursiveLockWait*>(arg);
Ian Rogers81d425b2012-09-27 16:03:43 -0700106 state->mu.Lock(Thread::Current());
Ian Rogersc604d732012-10-14 16:09:54 -0700107 state->cv.Signal(Thread::Current());
Ian Rogers81d425b2012-09-27 16:03:43 -0700108 state->mu.Unlock(Thread::Current());
Brian Carlstrom92c9a352012-06-21 18:21:59 -0700109 return NULL;
110 }
111
112 Mutex mu;
113 ConditionVariable cv;
114};
115
116// GCC has trouble with our mutex tests, so we have to turn off thread safety analysis.
117static void RecursiveLockWaitTest() NO_THREAD_SAFETY_ANALYSIS {
118 RecursiveLockWait state;
Ian Rogers81d425b2012-09-27 16:03:43 -0700119 state.mu.Lock(Thread::Current());
120 state.mu.Lock(Thread::Current());
Brian Carlstrom92c9a352012-06-21 18:21:59 -0700121
122 pthread_t pthread;
123 int pthread_create_result = pthread_create(&pthread, NULL, RecursiveLockWait::Callback, &state);
124 ASSERT_EQ(0, pthread_create_result);
125
Ian Rogersc604d732012-10-14 16:09:54 -0700126 state.cv.Wait(Thread::Current());
Brian Carlstrom92c9a352012-06-21 18:21:59 -0700127
Ian Rogers81d425b2012-09-27 16:03:43 -0700128 state.mu.Unlock(Thread::Current());
129 state.mu.Unlock(Thread::Current());
Ian Rogers23055dc2013-04-18 16:29:16 -0700130 EXPECT_EQ(pthread_join(pthread, NULL), 0);
Brian Carlstrom92c9a352012-06-21 18:21:59 -0700131}
132
133// This ensures we don't hang when waiting on a recursively locked mutex,
134// which is not supported with bare pthread_mutex_t.
135TEST_F(MutexTest, RecursiveLockWait) {
136 RecursiveLockWaitTest();
137}
138
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700139TEST_F(MutexTest, SharedLockUnlock) {
140 ReaderWriterMutex mu("test rwmutex");
Ian Rogers81d425b2012-09-27 16:03:43 -0700141 mu.AssertNotHeld(Thread::Current());
142 mu.AssertNotExclusiveHeld(Thread::Current());
143 mu.SharedLock(Thread::Current());
144 mu.AssertSharedHeld(Thread::Current());
145 mu.AssertNotExclusiveHeld(Thread::Current());
146 mu.SharedUnlock(Thread::Current());
147 mu.AssertNotHeld(Thread::Current());
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700148}
149
150TEST_F(MutexTest, ExclusiveLockUnlock) {
151 ReaderWriterMutex mu("test rwmutex");
Ian Rogers81d425b2012-09-27 16:03:43 -0700152 mu.AssertNotHeld(Thread::Current());
153 mu.ExclusiveLock(Thread::Current());
154 mu.AssertSharedHeld(Thread::Current());
155 mu.AssertExclusiveHeld(Thread::Current());
156 mu.ExclusiveUnlock(Thread::Current());
157 mu.AssertNotHeld(Thread::Current());
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700158}
159
160// GCC has trouble with our mutex tests, so we have to turn off thread safety analysis.
161static void SharedTryLockUnlockTest() NO_THREAD_SAFETY_ANALYSIS {
162 ReaderWriterMutex mu("test rwmutex");
Ian Rogers81d425b2012-09-27 16:03:43 -0700163 mu.AssertNotHeld(Thread::Current());
164 ASSERT_TRUE(mu.SharedTryLock(Thread::Current()));
165 mu.AssertSharedHeld(Thread::Current());
166 mu.SharedUnlock(Thread::Current());
167 mu.AssertNotHeld(Thread::Current());
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700168}
169
170TEST_F(MutexTest, SharedTryLockUnlock) {
171 SharedTryLockUnlockTest();
172}
173
Brian Carlstromcd74c4b2012-01-23 13:21:00 -0800174} // namespace art