blob: 8ddd50f031efc470e8ebde98b110ee89f56e5c4a [file] [log] [blame]
Elena Sayapina1af6a1f2014-06-20 16:58:37 +07001/*
2 * Copyright (C) 2014 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 */
16
Elena Sayapina1af6a1f2014-06-20 16:58:37 +070017#include "monitor.h"
18
Yi Kongc57c6802018-10-29 14:28:56 -070019#include <memory>
Elena Sayapina1af6a1f2014-06-20 16:58:37 +070020#include <string>
21
David Sehrc431b9d2018-03-02 12:01:51 -080022#include "base/atomic.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070023#include "barrier.h"
Vladimir Marko80afd022015-05-19 18:08:00 +010024#include "base/time_utils.h"
Vladimir Marko3481ba22015-04-13 12:22:36 +010025#include "class_linker-inl.h"
Elena Sayapina1af6a1f2014-06-20 16:58:37 +070026#include "common_runtime_test.h"
27#include "handle_scope-inl.h"
28#include "mirror/class-inl.h"
29#include "mirror/string-inl.h" // Strings are easiest to allocate
Mathieu Chartier4b0ef1c2016-07-29 16:26:01 -070030#include "object_lock.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070031#include "scoped_thread_state_change-inl.h"
Elena Sayapina1af6a1f2014-06-20 16:58:37 +070032#include "thread_pool.h"
Elena Sayapina1af6a1f2014-06-20 16:58:37 +070033
34namespace art {
35
36class MonitorTest : public CommonRuntimeTest {
37 protected:
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010038 void SetUpRuntimeOptions(RuntimeOptions *options) override {
Elena Sayapina1af6a1f2014-06-20 16:58:37 +070039 // Use a smaller heap
Andreas Gampe26761f72017-07-20 18:00:39 -070040 SetUpRuntimeOptionsForFillHeap(options);
41
Elena Sayapina1af6a1f2014-06-20 16:58:37 +070042 options->push_back(std::make_pair("-Xint", nullptr));
43 }
44 public:
45 std::unique_ptr<Monitor> monitor_;
46 Handle<mirror::String> object_;
47 Handle<mirror::String> second_object_;
48 Handle<mirror::String> watchdog_object_;
49 // One exception test is for waiting on another Thread's lock. This is used to race-free &
50 // loop-free pass
51 Thread* thread_;
52 std::unique_ptr<Barrier> barrier_;
53 std::unique_ptr<Barrier> complete_barrier_;
54 bool completed_;
55};
56
Elena Sayapina1af6a1f2014-06-20 16:58:37 +070057// Check that an exception can be thrown correctly.
58// This test is potentially racy, but the timeout is long enough that it should work.
59
60class CreateTask : public Task {
61 public:
Roland Levillain3887c462015-08-12 18:15:42 +010062 CreateTask(MonitorTest* monitor_test, uint64_t initial_sleep, int64_t millis, bool expected) :
Elena Sayapina1af6a1f2014-06-20 16:58:37 +070063 monitor_test_(monitor_test), initial_sleep_(initial_sleep), millis_(millis),
64 expected_(expected) {}
65
Andreas Gampefa6a1b02018-09-07 08:11:55 -070066 void Run(Thread* self) override {
Elena Sayapina1af6a1f2014-06-20 16:58:37 +070067 {
68 ScopedObjectAccess soa(self);
69
70 monitor_test_->thread_ = self; // Pass the Thread.
Mathieu Chartier2cebb242015-04-21 16:50:40 -070071 monitor_test_->object_.Get()->MonitorEnter(self); // Lock the object. This should transition
72 LockWord lock_after = monitor_test_->object_.Get()->GetLockWord(false); // it to thinLocked.
Elena Sayapina1af6a1f2014-06-20 16:58:37 +070073 LockWord::LockState new_state = lock_after.GetState();
74
75 // Cannot use ASSERT only, as analysis thinks we'll keep holding the mutex.
76 if (LockWord::LockState::kThinLocked != new_state) {
77 monitor_test_->object_.Get()->MonitorExit(self); // To appease analysis.
78 ASSERT_EQ(LockWord::LockState::kThinLocked, new_state); // To fail the test.
79 return;
80 }
81
82 // Force a fat lock by running identity hashcode to fill up lock word.
83 monitor_test_->object_.Get()->IdentityHashCode();
84 LockWord lock_after2 = monitor_test_->object_.Get()->GetLockWord(false);
85 LockWord::LockState new_state2 = lock_after2.GetState();
86
87 // Cannot use ASSERT only, as analysis thinks we'll keep holding the mutex.
88 if (LockWord::LockState::kFatLocked != new_state2) {
89 monitor_test_->object_.Get()->MonitorExit(self); // To appease analysis.
90 ASSERT_EQ(LockWord::LockState::kFatLocked, new_state2); // To fail the test.
91 return;
92 }
93 } // Need to drop the mutator lock to use the barrier.
94
95 monitor_test_->barrier_->Wait(self); // Let the other thread know we're done.
96
97 {
98 ScopedObjectAccess soa(self);
99
100 // Give the other task a chance to do its thing.
101 NanoSleep(initial_sleep_ * 1000 * 1000);
102
103 // Now try to Wait on the Monitor.
104 Monitor::Wait(self, monitor_test_->object_.Get(), millis_, 0, true,
105 ThreadState::kTimedWaiting);
106
107 // Check the exception status against what we expect.
108 EXPECT_EQ(expected_, self->IsExceptionPending());
109 if (expected_) {
110 self->ClearException();
111 }
112 }
113
114 monitor_test_->complete_barrier_->Wait(self); // Wait for test completion.
115
116 {
117 ScopedObjectAccess soa(self);
118 monitor_test_->object_.Get()->MonitorExit(self); // Release the object. Appeases analysis.
119 }
120 }
121
Andreas Gampefa6a1b02018-09-07 08:11:55 -0700122 void Finalize() override {
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700123 delete this;
124 }
125
126 private:
127 MonitorTest* monitor_test_;
128 uint64_t initial_sleep_;
129 int64_t millis_;
130 bool expected_;
131};
132
133
134class UseTask : public Task {
135 public:
136 UseTask(MonitorTest* monitor_test, uint64_t initial_sleep, int64_t millis, bool expected) :
137 monitor_test_(monitor_test), initial_sleep_(initial_sleep), millis_(millis),
138 expected_(expected) {}
139
Andreas Gampefa6a1b02018-09-07 08:11:55 -0700140 void Run(Thread* self) override {
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700141 monitor_test_->barrier_->Wait(self); // Wait for the other thread to set up the monitor.
142
143 {
144 ScopedObjectAccess soa(self);
145
146 // Give the other task a chance to do its thing.
147 NanoSleep(initial_sleep_ * 1000 * 1000);
148
149 Monitor::Wait(self, monitor_test_->object_.Get(), millis_, 0, true,
150 ThreadState::kTimedWaiting);
151
152 // Check the exception status against what we expect.
153 EXPECT_EQ(expected_, self->IsExceptionPending());
154 if (expected_) {
155 self->ClearException();
156 }
157 }
158
159 monitor_test_->complete_barrier_->Wait(self); // Wait for test completion.
160 }
161
Andreas Gampefa6a1b02018-09-07 08:11:55 -0700162 void Finalize() override {
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700163 delete this;
164 }
165
166 private:
167 MonitorTest* monitor_test_;
168 uint64_t initial_sleep_;
169 int64_t millis_;
170 bool expected_;
171};
172
173class InterruptTask : public Task {
174 public:
175 InterruptTask(MonitorTest* monitor_test, uint64_t initial_sleep, uint64_t millis) :
176 monitor_test_(monitor_test), initial_sleep_(initial_sleep), millis_(millis) {}
177
Andreas Gampefa6a1b02018-09-07 08:11:55 -0700178 void Run(Thread* self) override {
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700179 monitor_test_->barrier_->Wait(self); // Wait for the other thread to set up the monitor.
180
181 {
182 ScopedObjectAccess soa(self);
183
184 // Give the other task a chance to do its thing.
185 NanoSleep(initial_sleep_ * 1000 * 1000);
186
187 // Interrupt the other thread.
188 monitor_test_->thread_->Interrupt(self);
189
190 // Give it some more time to get to the exception code.
191 NanoSleep(millis_ * 1000 * 1000);
192
193 // Now try to Wait.
194 Monitor::Wait(self, monitor_test_->object_.Get(), 10, 0, true,
195 ThreadState::kTimedWaiting);
196
197 // No check here, as depending on scheduling we may or may not fail.
198 if (self->IsExceptionPending()) {
199 self->ClearException();
200 }
201 }
202
203 monitor_test_->complete_barrier_->Wait(self); // Wait for test completion.
204 }
205
Andreas Gampefa6a1b02018-09-07 08:11:55 -0700206 void Finalize() override {
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700207 delete this;
208 }
209
210 private:
211 MonitorTest* monitor_test_;
212 uint64_t initial_sleep_;
213 uint64_t millis_;
214};
215
216class WatchdogTask : public Task {
217 public:
218 explicit WatchdogTask(MonitorTest* monitor_test) : monitor_test_(monitor_test) {}
219
Andreas Gampefa6a1b02018-09-07 08:11:55 -0700220 void Run(Thread* self) override {
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700221 ScopedObjectAccess soa(self);
222
223 monitor_test_->watchdog_object_.Get()->MonitorEnter(self); // Lock the object.
224
225 monitor_test_->watchdog_object_.Get()->Wait(self, 30 * 1000, 0); // Wait for 30s, or being
226 // woken up.
227
228 monitor_test_->watchdog_object_.Get()->MonitorExit(self); // Release the lock.
229
230 if (!monitor_test_->completed_) {
231 LOG(FATAL) << "Watchdog timeout!";
232 }
233 }
234
Andreas Gampefa6a1b02018-09-07 08:11:55 -0700235 void Finalize() override {
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700236 delete this;
237 }
238
239 private:
240 MonitorTest* monitor_test_;
241};
242
243static void CommonWaitSetup(MonitorTest* test, ClassLinker* class_linker, uint64_t create_sleep,
244 int64_t c_millis, bool c_expected, bool interrupt, uint64_t use_sleep,
245 int64_t u_millis, bool u_expected, const char* pool_name) {
Mathieu Chartiered150002015-08-28 11:16:54 -0700246 Thread* const self = Thread::Current();
247 ScopedObjectAccess soa(self);
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700248 // First create the object we lock. String is easiest.
Mathieu Chartiered150002015-08-28 11:16:54 -0700249 StackHandleScope<3> hs(soa.Self());
250 test->object_ = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "hello, world!"));
251 test->watchdog_object_ = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self,
252 "hello, world!"));
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700253
254 // Create the barrier used to synchronize.
Yi Kongc57c6802018-10-29 14:28:56 -0700255 test->barrier_ = std::make_unique<Barrier>(2);
256 test->complete_barrier_ = std::make_unique<Barrier>(3);
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700257 test->completed_ = false;
258
Mathieu Chartiered150002015-08-28 11:16:54 -0700259 // Our job: Fill the heap, then try Wait.
Andreas Gampe26761f72017-07-20 18:00:39 -0700260 {
261 VariableSizedHandleScope vhs(soa.Self());
262 test->FillHeap(soa.Self(), class_linker, &vhs);
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700263
Andreas Gampe26761f72017-07-20 18:00:39 -0700264 // Now release everything.
Mathieu Chartiered150002015-08-28 11:16:54 -0700265 }
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700266
Mathieu Chartiered150002015-08-28 11:16:54 -0700267 // Need to drop the mutator lock to allow barriers.
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700268 ScopedThreadSuspension sts(soa.Self(), kNative);
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700269 ThreadPool thread_pool(pool_name, 3);
270 thread_pool.AddTask(self, new CreateTask(test, create_sleep, c_millis, c_expected));
271 if (interrupt) {
272 thread_pool.AddTask(self, new InterruptTask(test, use_sleep, static_cast<uint64_t>(u_millis)));
273 } else {
274 thread_pool.AddTask(self, new UseTask(test, use_sleep, u_millis, u_expected));
275 }
276 thread_pool.AddTask(self, new WatchdogTask(test));
277 thread_pool.StartWorkers(self);
278
279 // Wait on completion barrier.
Mathieu Chartiered150002015-08-28 11:16:54 -0700280 test->complete_barrier_->Wait(self);
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700281 test->completed_ = true;
282
283 // Wake the watchdog.
284 {
Mathieu Chartiered150002015-08-28 11:16:54 -0700285 ScopedObjectAccess soa2(self);
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700286 test->watchdog_object_.Get()->MonitorEnter(self); // Lock the object.
287 test->watchdog_object_.Get()->NotifyAll(self); // Wake up waiting parties.
288 test->watchdog_object_.Get()->MonitorExit(self); // Release the lock.
289 }
290
291 thread_pool.StopWorkers(self);
292}
293
294
295// First test: throwing an exception when trying to wait in Monitor with another thread.
296TEST_F(MonitorTest, CheckExceptionsWait1) {
297 // Make the CreateTask wait 10ms, the UseTask wait 10ms.
298 // => The use task will get the lock first and get to self == owner check.
Andreas Gampe369810a2015-01-14 19:53:31 -0800299 // This will lead to OOM and monitor error messages in the log.
300 ScopedLogSeverity sls(LogSeverity::FATAL);
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700301 CommonWaitSetup(this, class_linker_, 10, 50, false, false, 2, 50, true,
302 "Monitor test thread pool 1");
303}
304
305// Second test: throwing an exception for invalid wait time.
306TEST_F(MonitorTest, CheckExceptionsWait2) {
307 // Make the CreateTask wait 0ms, the UseTask wait 10ms.
308 // => The create task will get the lock first and get to ms >= 0
Andreas Gampe369810a2015-01-14 19:53:31 -0800309 // This will lead to OOM and monitor error messages in the log.
310 ScopedLogSeverity sls(LogSeverity::FATAL);
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700311 CommonWaitSetup(this, class_linker_, 0, -1, true, false, 10, 50, true,
312 "Monitor test thread pool 2");
313}
314
315// Third test: throwing an interrupted-exception.
316TEST_F(MonitorTest, CheckExceptionsWait3) {
317 // Make the CreateTask wait 0ms, then Wait for a long time. Make the InterruptTask wait 10ms,
318 // after which it will interrupt the create task and then wait another 10ms.
319 // => The create task will get to the interrupted-exception throw.
Andreas Gampe369810a2015-01-14 19:53:31 -0800320 // This will lead to OOM and monitor error messages in the log.
321 ScopedLogSeverity sls(LogSeverity::FATAL);
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700322 CommonWaitSetup(this, class_linker_, 0, 500, true, true, 10, 50, true,
323 "Monitor test thread pool 3");
324}
325
Mathieu Chartier4b0ef1c2016-07-29 16:26:01 -0700326class TryLockTask : public Task {
327 public:
328 explicit TryLockTask(Handle<mirror::Object> obj) : obj_(obj) {}
329
Andreas Gampefa6a1b02018-09-07 08:11:55 -0700330 void Run(Thread* self) override {
Mathieu Chartier4b0ef1c2016-07-29 16:26:01 -0700331 ScopedObjectAccess soa(self);
332 // Lock is held by other thread, try lock should fail.
333 ObjectTryLock<mirror::Object> lock(self, obj_);
334 EXPECT_FALSE(lock.Acquired());
335 }
336
Andreas Gampefa6a1b02018-09-07 08:11:55 -0700337 void Finalize() override {
Mathieu Chartier4b0ef1c2016-07-29 16:26:01 -0700338 delete this;
339 }
340
341 private:
342 Handle<mirror::Object> obj_;
343};
344
345// Test trylock in deadlock scenarios.
346TEST_F(MonitorTest, TestTryLock) {
347 ScopedLogSeverity sls(LogSeverity::FATAL);
348
349 Thread* const self = Thread::Current();
350 ThreadPool thread_pool("the pool", 2);
351 ScopedObjectAccess soa(self);
Andreas Gampe38cea842016-11-03 13:06:25 -0700352 StackHandleScope<1> hs(self);
Mathieu Chartier4b0ef1c2016-07-29 16:26:01 -0700353 Handle<mirror::Object> obj1(
354 hs.NewHandle<mirror::Object>(mirror::String::AllocFromModifiedUtf8(self, "hello, world!")));
Mathieu Chartier4b0ef1c2016-07-29 16:26:01 -0700355 {
356 ObjectLock<mirror::Object> lock1(self, obj1);
Mathieu Chartier4b0ef1c2016-07-29 16:26:01 -0700357 {
358 ObjectTryLock<mirror::Object> trylock(self, obj1);
359 EXPECT_TRUE(trylock.Acquired());
360 }
361 // Test failure case.
362 thread_pool.AddTask(self, new TryLockTask(obj1));
363 thread_pool.StartWorkers(self);
364 ScopedThreadSuspension sts(self, kSuspended);
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700365 thread_pool.Wait(Thread::Current(), /*do_work=*/false, /*may_hold_locks=*/false);
Mathieu Chartier4b0ef1c2016-07-29 16:26:01 -0700366 }
367 // Test that the trylock actually locks the object.
368 {
369 ObjectTryLock<mirror::Object> trylock(self, obj1);
370 EXPECT_TRUE(trylock.Acquired());
371 obj1->Notify(self);
372 // Since we hold the lock there should be no monitor state exeception.
373 self->AssertNoPendingException();
374 }
375 thread_pool.StopWorkers(self);
376}
377
378
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700379} // namespace art