blob: 69507d11d2067998c8b497483c31f5222c193850 [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) {
31 mu.AssertNotHeld();
32 } else {
33 mu.AssertHeld();
34 }
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);
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080041 mu.Lock();
Elliott Hughes3efb8412012-03-16 16:09:38 -070042 MutexTester::AssertDepth(mu, 1U);
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080043 mu.Unlock();
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);
Elliott Hughes81414052012-06-18 16:43:50 -070051 ASSERT_TRUE(mu.TryLock());
52 MutexTester::AssertDepth(mu, 1U);
53 mu.Unlock();
54 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 {
63 Mutex mu("test mutex");
64 MutexTester::AssertDepth(mu, 0U);
65 mu.Lock();
66 MutexTester::AssertDepth(mu, 1U);
67 mu.Lock();
68 MutexTester::AssertDepth(mu, 2U);
69 mu.Unlock();
Elliott Hughes3efb8412012-03-16 16:09:38 -070070 MutexTester::AssertDepth(mu, 1U);
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080071 mu.Unlock();
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 {
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080081 Mutex mu("test mutex");
Elliott Hughes3efb8412012-03-16 16:09:38 -070082 MutexTester::AssertDepth(mu, 0U);
Elliott Hughesf8349362012-06-18 15:00:06 -070083 ASSERT_TRUE(mu.TryLock());
Elliott Hughes3efb8412012-03-16 16:09:38 -070084 MutexTester::AssertDepth(mu, 1U);
Elliott Hughesf8349362012-06-18 15:00:06 -070085 ASSERT_TRUE(mu.TryLock());
Elliott Hughes3efb8412012-03-16 16:09:38 -070086 MutexTester::AssertDepth(mu, 2U);
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080087 mu.Unlock();
Elliott Hughes3efb8412012-03-16 16:09:38 -070088 MutexTester::AssertDepth(mu, 1U);
Brian Carlstromcd74c4b2012-01-23 13:21:00 -080089 mu.Unlock();
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 {
99 explicit RecursiveLockWait() : mu("test mutex"), cv("test condition variable") {}
100
101 static void* Callback(void* arg) {
102 RecursiveLockWait* state = reinterpret_cast<RecursiveLockWait*>(arg);
103 state->mu.Lock();
104 state->cv.Signal();
105 state->mu.Unlock();
106 return NULL;
107 }
108
109 Mutex mu;
110 ConditionVariable cv;
111};
112
113// GCC has trouble with our mutex tests, so we have to turn off thread safety analysis.
114static void RecursiveLockWaitTest() NO_THREAD_SAFETY_ANALYSIS {
115 RecursiveLockWait state;
116 state.mu.Lock();
117 state.mu.Lock();
118
119 pthread_t pthread;
120 int pthread_create_result = pthread_create(&pthread, NULL, RecursiveLockWait::Callback, &state);
121 ASSERT_EQ(0, pthread_create_result);
122
123 state.cv.Wait(state.mu);
124
125 state.mu.Unlock();
126 state.mu.Unlock();
127}
128
129// This ensures we don't hang when waiting on a recursively locked mutex,
130// which is not supported with bare pthread_mutex_t.
131TEST_F(MutexTest, RecursiveLockWait) {
132 RecursiveLockWaitTest();
133}
134
Brian Carlstromcd74c4b2012-01-23 13:21:00 -0800135} // namespace art