1 /*
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
17 #include "monitor.h"
18
19 #include <memory>
20 #include <string>
21
22 #include "base/atomic.h"
23 #include "barrier.h"
24 #include "base/time_utils.h"
25 #include "class_linker-inl.h"
26 #include "common_runtime_test.h"
27 #include "handle_scope-inl.h"
28 #include "jni/java_vm_ext.h"
29 #include "mirror/class-inl.h"
30 #include "mirror/string-inl.h" // Strings are easiest to allocate
31 #include "object_lock.h"
32 #include "scoped_thread_state_change-inl.h"
33 #include "thread_pool.h"
34
35 namespace art {
36
37 class MonitorTest : public CommonRuntimeTest {
38 protected:
MonitorTest()39 MonitorTest() {
40 use_boot_image_ = true; // Make the Runtime creation cheaper.
41 }
42
SetUpRuntimeOptions(RuntimeOptions * options)43 void SetUpRuntimeOptions(RuntimeOptions *options) override {
44 // Use a smaller heap
45 SetUpRuntimeOptionsForFillHeap(options);
46
47 options->push_back(std::make_pair("-Xint", nullptr));
48 }
49
50 public:
51 std::unique_ptr<Monitor> monitor_;
52 jobject object_;
53 jobject watchdog_object_;
54 // One exception test is for waiting on another Thread's lock. This is used to race-free &
55 // loop-free pass
56 Thread* thread_;
57 std::unique_ptr<Barrier> barrier_;
58 std::unique_ptr<Barrier> complete_barrier_;
59 bool completed_;
60 };
61
62 // Check that an exception can be thrown correctly.
63 // This test is potentially racy, but the timeout is long enough that it should work.
64
65 class CreateTask : public Task {
66 public:
CreateTask(MonitorTest * monitor_test,uint64_t initial_sleep,int64_t millis,bool expected)67 CreateTask(MonitorTest* monitor_test, uint64_t initial_sleep, int64_t millis, bool expected) :
68 monitor_test_(monitor_test), initial_sleep_(initial_sleep), millis_(millis),
69 expected_(expected) {}
70
Run(Thread * self)71 void Run(Thread* self) override {
72 ScopedObjectAccess soa(self);
73 StackHandleScope<1u> hs(self);
74 Handle<mirror::Object> obj = hs.NewHandle(soa.Decode<mirror::Object>(monitor_test_->object_));
75
76 monitor_test_->thread_ = self; // Pass the Thread.
77 obj->MonitorEnter(self); // Lock the object. This should transition
78 LockWord lock_after = obj->GetLockWord(false); // it to thinLocked.
79 LockWord::LockState new_state = lock_after.GetState();
80
81 // Cannot use ASSERT only, as analysis thinks we'll keep holding the mutex.
82 if (LockWord::LockState::kThinLocked != new_state) {
83 obj->MonitorExit(self); // To appease analysis.
84 ASSERT_EQ(LockWord::LockState::kThinLocked, new_state); // To fail the test.
85 return;
86 }
87
88 // Force a fat lock by running identity hashcode to fill up lock word.
89 obj->IdentityHashCode();
90 LockWord lock_after2 = obj->GetLockWord(false);
91 LockWord::LockState new_state2 = lock_after2.GetState();
92
93 // Cannot use ASSERT only, as analysis thinks we'll keep holding the mutex.
94 if (LockWord::LockState::kFatLocked != new_state2) {
95 obj->MonitorExit(self); // To appease analysis.
96 ASSERT_EQ(LockWord::LockState::kFatLocked, new_state2); // To fail the test.
97 return;
98 }
99
100 {
101 // Need to drop the mutator lock to use the barrier.
102 ScopedThreadSuspension sts(self, ThreadState::kSuspended);
103 monitor_test_->barrier_->Wait(self); // Let the other thread know we're done.
104 }
105
106 // Give the other task a chance to do its thing.
107 NanoSleep(initial_sleep_ * 1000 * 1000);
108
109 // Now try to Wait on the Monitor.
110 Monitor::Wait(self, obj.Get(), millis_, 0, true, ThreadState::kTimedWaiting);
111
112 // Check the exception status against what we expect.
113 EXPECT_EQ(expected_, self->IsExceptionPending());
114 if (expected_) {
115 self->ClearException();
116 }
117
118 {
119 // Need to drop the mutator lock to use the barrier.
120 ScopedThreadSuspension sts(self, ThreadState::kSuspended);
121 monitor_test_->complete_barrier_->Wait(self); // Wait for test completion.
122 }
123
124 obj->MonitorExit(self); // Release the object. Appeases analysis.
125 }
126
Finalize()127 void Finalize() override {
128 delete this;
129 }
130
131 private:
132 MonitorTest* monitor_test_;
133 uint64_t initial_sleep_;
134 int64_t millis_;
135 bool expected_;
136 };
137
138
139 class UseTask : public Task {
140 public:
UseTask(MonitorTest * monitor_test,uint64_t initial_sleep,int64_t millis,bool expected)141 UseTask(MonitorTest* monitor_test, uint64_t initial_sleep, int64_t millis, bool expected) :
142 monitor_test_(monitor_test), initial_sleep_(initial_sleep), millis_(millis),
143 expected_(expected) {}
144
Run(Thread * self)145 void Run(Thread* self) override {
146 monitor_test_->barrier_->Wait(self); // Wait for the other thread to set up the monitor.
147
148 {
149 ScopedObjectAccess soa(self);
150
151 // Give the other task a chance to do its thing.
152 NanoSleep(initial_sleep_ * 1000 * 1000);
153
154 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(monitor_test_->object_);
155 Monitor::Wait(self, obj, millis_, 0, true, ThreadState::kTimedWaiting);
156
157 // Check the exception status against what we expect.
158 EXPECT_EQ(expected_, self->IsExceptionPending());
159 if (expected_) {
160 self->ClearException();
161 }
162 }
163
164 monitor_test_->complete_barrier_->Wait(self); // Wait for test completion.
165 }
166
Finalize()167 void Finalize() override {
168 delete this;
169 }
170
171 private:
172 MonitorTest* monitor_test_;
173 uint64_t initial_sleep_;
174 int64_t millis_;
175 bool expected_;
176 };
177
178 class InterruptTask : public Task {
179 public:
InterruptTask(MonitorTest * monitor_test,uint64_t initial_sleep,uint64_t millis)180 InterruptTask(MonitorTest* monitor_test, uint64_t initial_sleep, uint64_t millis) :
181 monitor_test_(monitor_test), initial_sleep_(initial_sleep), millis_(millis) {}
182
Run(Thread * self)183 void Run(Thread* self) override {
184 monitor_test_->barrier_->Wait(self); // Wait for the other thread to set up the monitor.
185
186 {
187 ScopedObjectAccess soa(self);
188
189 // Give the other task a chance to do its thing.
190 NanoSleep(initial_sleep_ * 1000 * 1000);
191
192 // Interrupt the other thread.
193 monitor_test_->thread_->Interrupt(self);
194
195 // Give it some more time to get to the exception code.
196 NanoSleep(millis_ * 1000 * 1000);
197
198 // Now try to Wait.
199 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(monitor_test_->object_);
200 Monitor::Wait(self, obj, 10, 0, true, ThreadState::kTimedWaiting);
201
202 // No check here, as depending on scheduling we may or may not fail.
203 if (self->IsExceptionPending()) {
204 self->ClearException();
205 }
206 }
207
208 monitor_test_->complete_barrier_->Wait(self); // Wait for test completion.
209 }
210
Finalize()211 void Finalize() override {
212 delete this;
213 }
214
215 private:
216 MonitorTest* monitor_test_;
217 uint64_t initial_sleep_;
218 uint64_t millis_;
219 };
220
221 class WatchdogTask : public Task {
222 public:
WatchdogTask(MonitorTest * monitor_test)223 explicit WatchdogTask(MonitorTest* monitor_test) : monitor_test_(monitor_test) {}
224
Run(Thread * self)225 void Run(Thread* self) override {
226 ScopedObjectAccess soa(self);
227 StackHandleScope<1u> hs(self);
228 Handle<mirror::Object> watchdog_obj =
229 hs.NewHandle(soa.Decode<mirror::Object>(monitor_test_->watchdog_object_));
230
231 watchdog_obj->MonitorEnter(self); // Lock the object.
232
233 watchdog_obj->Wait(self, 30 * 1000, 0); // Wait for 30s, or being woken up.
234
235 watchdog_obj->MonitorExit(self); // Release the lock.
236
237 if (!monitor_test_->completed_) {
238 LOG(FATAL) << "Watchdog timeout!";
239 }
240 }
241
Finalize()242 void Finalize() override {
243 delete this;
244 }
245
246 private:
247 MonitorTest* monitor_test_;
248 };
249
CommonWaitSetup(MonitorTest * test,ClassLinker * class_linker,uint64_t create_sleep,int64_t c_millis,bool c_expected,bool interrupt,uint64_t use_sleep,int64_t u_millis,bool u_expected,const char * pool_name)250 static void CommonWaitSetup(MonitorTest* test, ClassLinker* class_linker, uint64_t create_sleep,
251 int64_t c_millis, bool c_expected, bool interrupt, uint64_t use_sleep,
252 int64_t u_millis, bool u_expected, const char* pool_name) {
253 Thread* const self = Thread::Current();
254 ScopedObjectAccess soa(self);
255 // First create the object we lock. String is easiest.
256 StackHandleScope<2u> hs(soa.Self());
257 Handle<mirror::Object> obj =
258 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "hello, world!"));
259 test->object_ = soa.Vm()->AddGlobalRef(self, obj.Get());
260 ASSERT_TRUE(test->object_ != nullptr);
261 Handle<mirror::Object> watchdog_obj =
262 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "hello, world!"));
263 test->watchdog_object_ = soa.Vm()->AddGlobalRef(self, watchdog_obj.Get());
264 ASSERT_TRUE(test->watchdog_object_ != nullptr);
265
266 // Create the barrier used to synchronize.
267 test->barrier_ = std::make_unique<Barrier>(2);
268 test->complete_barrier_ = std::make_unique<Barrier>(3);
269 test->completed_ = false;
270
271 // Our job: Fill the heap, then try Wait.
272 {
273 VariableSizedHandleScope vhs(soa.Self());
274 test->FillHeap(soa.Self(), class_linker, &vhs);
275
276 // Now release everything.
277 }
278
279 // Need to drop the mutator lock to allow barriers.
280 ScopedThreadSuspension sts(soa.Self(), ThreadState::kNative);
281 ThreadPool thread_pool(pool_name, 3);
282 thread_pool.AddTask(self, new CreateTask(test, create_sleep, c_millis, c_expected));
283 if (interrupt) {
284 thread_pool.AddTask(self, new InterruptTask(test, use_sleep, static_cast<uint64_t>(u_millis)));
285 } else {
286 thread_pool.AddTask(self, new UseTask(test, use_sleep, u_millis, u_expected));
287 }
288 thread_pool.AddTask(self, new WatchdogTask(test));
289 thread_pool.StartWorkers(self);
290
291 // Wait on completion barrier.
292 test->complete_barrier_->Wait(self);
293 test->completed_ = true;
294
295 // Wake the watchdog.
296 {
297 ScopedObjectAccess soa2(self);
298 watchdog_obj->MonitorEnter(self); // Lock the object.
299 watchdog_obj->NotifyAll(self); // Wake up waiting parties.
300 watchdog_obj->MonitorExit(self); // Release the lock.
301 }
302
303 thread_pool.StopWorkers(self);
304 }
305
306
307 // First test: throwing an exception when trying to wait in Monitor with another thread.
TEST_F(MonitorTest,CheckExceptionsWait1)308 TEST_F(MonitorTest, CheckExceptionsWait1) {
309 // Make the CreateTask wait 10ms, the UseTask wait 10ms.
310 // => The use task will get the lock first and get to self == owner check.
311 // This will lead to OOM and monitor error messages in the log.
312 ScopedLogSeverity sls(LogSeverity::FATAL);
313 CommonWaitSetup(this, class_linker_, 10, 50, false, false, 2, 50, true,
314 "Monitor test thread pool 1");
315 }
316
317 // Second test: throwing an exception for invalid wait time.
TEST_F(MonitorTest,CheckExceptionsWait2)318 TEST_F(MonitorTest, CheckExceptionsWait2) {
319 // Make the CreateTask wait 0ms, the UseTask wait 10ms.
320 // => The create task will get the lock first and get to ms >= 0
321 // This will lead to OOM and monitor error messages in the log.
322 ScopedLogSeverity sls(LogSeverity::FATAL);
323 CommonWaitSetup(this, class_linker_, 0, -1, true, false, 10, 50, true,
324 "Monitor test thread pool 2");
325 }
326
327 // Third test: throwing an interrupted-exception.
TEST_F(MonitorTest,CheckExceptionsWait3)328 TEST_F(MonitorTest, CheckExceptionsWait3) {
329 // Make the CreateTask wait 0ms, then Wait for a long time. Make the InterruptTask wait 10ms,
330 // after which it will interrupt the create task and then wait another 10ms.
331 // => The create task will get to the interrupted-exception throw.
332 // This will lead to OOM and monitor error messages in the log.
333 ScopedLogSeverity sls(LogSeverity::FATAL);
334 CommonWaitSetup(this, class_linker_, 0, 500, true, true, 10, 50, true,
335 "Monitor test thread pool 3");
336 }
337
338 class TryLockTask : public Task {
339 public:
TryLockTask(jobject obj)340 explicit TryLockTask(jobject obj) : obj_(obj) {}
341
Run(Thread * self)342 void Run(Thread* self) override {
343 ScopedObjectAccess soa(self);
344 StackHandleScope<1u> hs(self);
345 Handle<mirror::Object> obj = hs.NewHandle(soa.Decode<mirror::Object>(obj_));
346 // Lock is held by other thread, try lock should fail.
347 ObjectTryLock<mirror::Object> lock(self, obj);
348 EXPECT_FALSE(lock.Acquired());
349 }
350
Finalize()351 void Finalize() override {
352 delete this;
353 }
354
355 private:
356 jobject obj_;
357 };
358
359 // Test trylock in deadlock scenarios.
TEST_F(MonitorTest,TestTryLock)360 TEST_F(MonitorTest, TestTryLock) {
361 ScopedLogSeverity sls(LogSeverity::FATAL);
362
363 Thread* const self = Thread::Current();
364 ThreadPool thread_pool("the pool", 2);
365 ScopedObjectAccess soa(self);
366 StackHandleScope<1> hs(self);
367 Handle<mirror::Object> obj1(
368 hs.NewHandle<mirror::Object>(mirror::String::AllocFromModifiedUtf8(self, "hello, world!")));
369 jobject g_obj1 = soa.Vm()->AddGlobalRef(self, obj1.Get());
370 ASSERT_TRUE(g_obj1 != nullptr);
371 {
372 ObjectLock<mirror::Object> lock1(self, obj1);
373 {
374 ObjectTryLock<mirror::Object> trylock(self, obj1);
375 EXPECT_TRUE(trylock.Acquired());
376 }
377 // Test failure case.
378 thread_pool.AddTask(self, new TryLockTask(g_obj1));
379 thread_pool.StartWorkers(self);
380 ScopedThreadSuspension sts(self, ThreadState::kSuspended);
381 thread_pool.Wait(Thread::Current(), /*do_work=*/false, /*may_hold_locks=*/false);
382 }
383 // Test that the trylock actually locks the object.
384 {
385 ObjectTryLock<mirror::Object> trylock(self, obj1);
386 EXPECT_TRUE(trylock.Acquired());
387 obj1->Notify(self);
388 // Since we hold the lock there should be no monitor state exeception.
389 self->AssertNoPendingException();
390 }
391 thread_pool.StopWorkers(self);
392 }
393
394
395 } // namespace art
396