blob: 48d256c98511825f312cb0eb54370afe87d90d29 [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
17#include "barrier.h"
18#include "monitor.h"
19
20#include <string>
21
22#include "atomic.h"
Vladimir Marko80afd022015-05-19 18:08:00 +010023#include "base/time_utils.h"
Vladimir Marko3481ba22015-04-13 12:22:36 +010024#include "class_linker-inl.h"
Elena Sayapina1af6a1f2014-06-20 16:58:37 +070025#include "common_runtime_test.h"
26#include "handle_scope-inl.h"
27#include "mirror/class-inl.h"
28#include "mirror/string-inl.h" // Strings are easiest to allocate
Mathieu Chartier23da0262016-07-29 16:26:01 -070029#include "object_lock.h"
Ian Rogerse63db272014-07-15 15:36:11 -070030#include "scoped_thread_state_change.h"
Elena Sayapina1af6a1f2014-06-20 16:58:37 +070031#include "thread_pool.h"
Elena Sayapina1af6a1f2014-06-20 16:58:37 +070032
33namespace art {
34
35class MonitorTest : public CommonRuntimeTest {
36 protected:
Ian Rogerse63db272014-07-15 15:36:11 -070037 void SetUpRuntimeOptions(RuntimeOptions *options) OVERRIDE {
Elena Sayapina1af6a1f2014-06-20 16:58:37 +070038 // Use a smaller heap
39 for (std::pair<std::string, const void*>& pair : *options) {
40 if (pair.first.find("-Xmx") == 0) {
41 pair.first = "-Xmx4M"; // Smallest we can go.
42 }
43 }
44 options->push_back(std::make_pair("-Xint", nullptr));
45 }
46 public:
47 std::unique_ptr<Monitor> monitor_;
48 Handle<mirror::String> object_;
49 Handle<mirror::String> second_object_;
50 Handle<mirror::String> watchdog_object_;
51 // One exception test is for waiting on another Thread's lock. This is used to race-free &
52 // loop-free pass
53 Thread* thread_;
54 std::unique_ptr<Barrier> barrier_;
55 std::unique_ptr<Barrier> complete_barrier_;
56 bool completed_;
57};
58
59// Fill the heap.
60static const size_t kMaxHandles = 1000000; // Use arbitrary large amount for now.
61static void FillHeap(Thread* self, ClassLinker* class_linker,
62 std::unique_ptr<StackHandleScope<kMaxHandles>>* hsp,
Andreas Gampe5a4b8a22014-09-11 08:30:08 -070063 std::vector<MutableHandle<mirror::Object>>* handles)
Mathieu Chartier90443472015-07-16 20:32:27 -070064 SHARED_REQUIRES(Locks::mutator_lock_) {
Elena Sayapina1af6a1f2014-06-20 16:58:37 +070065 Runtime::Current()->GetHeap()->SetIdealFootprint(1 * GB);
66
67 hsp->reset(new StackHandleScope<kMaxHandles>(self));
68 // Class java.lang.Object.
69 Handle<mirror::Class> c((*hsp)->NewHandle(class_linker->FindSystemClass(self,
70 "Ljava/lang/Object;")));
71 // Array helps to fill memory faster.
72 Handle<mirror::Class> ca((*hsp)->NewHandle(class_linker->FindSystemClass(self,
73 "[Ljava/lang/Object;")));
74
75 // Start allocating with 128K
76 size_t length = 128 * KB / 4;
77 while (length > 10) {
Andreas Gampe5a4b8a22014-09-11 08:30:08 -070078 MutableHandle<mirror::Object> h((*hsp)->NewHandle<mirror::Object>(
Elena Sayapina1af6a1f2014-06-20 16:58:37 +070079 mirror::ObjectArray<mirror::Object>::Alloc(self, ca.Get(), length / 4)));
80 if (self->IsExceptionPending() || h.Get() == nullptr) {
81 self->ClearException();
82
83 // Try a smaller length
84 length = length / 8;
85 // Use at most half the reported free space.
86 size_t mem = Runtime::Current()->GetHeap()->GetFreeMemory();
87 if (length * 8 > mem) {
88 length = mem / 8;
89 }
90 } else {
91 handles->push_back(h);
92 }
93 }
94
95 // Allocate simple objects till it fails.
96 while (!self->IsExceptionPending()) {
Andreas Gampe5a4b8a22014-09-11 08:30:08 -070097 MutableHandle<mirror::Object> h = (*hsp)->NewHandle<mirror::Object>(c->AllocObject(self));
Elena Sayapina1af6a1f2014-06-20 16:58:37 +070098 if (!self->IsExceptionPending() && h.Get() != nullptr) {
99 handles->push_back(h);
100 }
101 }
102 self->ClearException();
103}
104
105// Check that an exception can be thrown correctly.
106// This test is potentially racy, but the timeout is long enough that it should work.
107
108class CreateTask : public Task {
109 public:
Roland Levillain3887c462015-08-12 18:15:42 +0100110 CreateTask(MonitorTest* monitor_test, uint64_t initial_sleep, int64_t millis, bool expected) :
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700111 monitor_test_(monitor_test), initial_sleep_(initial_sleep), millis_(millis),
112 expected_(expected) {}
113
114 void Run(Thread* self) {
115 {
116 ScopedObjectAccess soa(self);
117
118 monitor_test_->thread_ = self; // Pass the Thread.
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700119 monitor_test_->object_.Get()->MonitorEnter(self); // Lock the object. This should transition
120 LockWord lock_after = monitor_test_->object_.Get()->GetLockWord(false); // it to thinLocked.
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700121 LockWord::LockState new_state = lock_after.GetState();
122
123 // Cannot use ASSERT only, as analysis thinks we'll keep holding the mutex.
124 if (LockWord::LockState::kThinLocked != new_state) {
125 monitor_test_->object_.Get()->MonitorExit(self); // To appease analysis.
126 ASSERT_EQ(LockWord::LockState::kThinLocked, new_state); // To fail the test.
127 return;
128 }
129
130 // Force a fat lock by running identity hashcode to fill up lock word.
131 monitor_test_->object_.Get()->IdentityHashCode();
132 LockWord lock_after2 = monitor_test_->object_.Get()->GetLockWord(false);
133 LockWord::LockState new_state2 = lock_after2.GetState();
134
135 // Cannot use ASSERT only, as analysis thinks we'll keep holding the mutex.
136 if (LockWord::LockState::kFatLocked != new_state2) {
137 monitor_test_->object_.Get()->MonitorExit(self); // To appease analysis.
138 ASSERT_EQ(LockWord::LockState::kFatLocked, new_state2); // To fail the test.
139 return;
140 }
141 } // Need to drop the mutator lock to use the barrier.
142
143 monitor_test_->barrier_->Wait(self); // Let the other thread know we're done.
144
145 {
146 ScopedObjectAccess soa(self);
147
148 // Give the other task a chance to do its thing.
149 NanoSleep(initial_sleep_ * 1000 * 1000);
150
151 // Now try to Wait on the Monitor.
152 Monitor::Wait(self, monitor_test_->object_.Get(), millis_, 0, true,
153 ThreadState::kTimedWaiting);
154
155 // Check the exception status against what we expect.
156 EXPECT_EQ(expected_, self->IsExceptionPending());
157 if (expected_) {
158 self->ClearException();
159 }
160 }
161
162 monitor_test_->complete_barrier_->Wait(self); // Wait for test completion.
163
164 {
165 ScopedObjectAccess soa(self);
166 monitor_test_->object_.Get()->MonitorExit(self); // Release the object. Appeases analysis.
167 }
168 }
169
170 void Finalize() {
171 delete this;
172 }
173
174 private:
175 MonitorTest* monitor_test_;
176 uint64_t initial_sleep_;
177 int64_t millis_;
178 bool expected_;
179};
180
181
182class UseTask : public Task {
183 public:
184 UseTask(MonitorTest* monitor_test, uint64_t initial_sleep, int64_t millis, bool expected) :
185 monitor_test_(monitor_test), initial_sleep_(initial_sleep), millis_(millis),
186 expected_(expected) {}
187
188 void Run(Thread* self) {
189 monitor_test_->barrier_->Wait(self); // Wait for the other thread to set up the monitor.
190
191 {
192 ScopedObjectAccess soa(self);
193
194 // Give the other task a chance to do its thing.
195 NanoSleep(initial_sleep_ * 1000 * 1000);
196
197 Monitor::Wait(self, monitor_test_->object_.Get(), millis_, 0, true,
198 ThreadState::kTimedWaiting);
199
200 // Check the exception status against what we expect.
201 EXPECT_EQ(expected_, self->IsExceptionPending());
202 if (expected_) {
203 self->ClearException();
204 }
205 }
206
207 monitor_test_->complete_barrier_->Wait(self); // Wait for test completion.
208 }
209
210 void Finalize() {
211 delete this;
212 }
213
214 private:
215 MonitorTest* monitor_test_;
216 uint64_t initial_sleep_;
217 int64_t millis_;
218 bool expected_;
219};
220
221class InterruptTask : public Task {
222 public:
223 InterruptTask(MonitorTest* monitor_test, uint64_t initial_sleep, uint64_t millis) :
224 monitor_test_(monitor_test), initial_sleep_(initial_sleep), millis_(millis) {}
225
226 void Run(Thread* self) {
227 monitor_test_->barrier_->Wait(self); // Wait for the other thread to set up the monitor.
228
229 {
230 ScopedObjectAccess soa(self);
231
232 // Give the other task a chance to do its thing.
233 NanoSleep(initial_sleep_ * 1000 * 1000);
234
235 // Interrupt the other thread.
236 monitor_test_->thread_->Interrupt(self);
237
238 // Give it some more time to get to the exception code.
239 NanoSleep(millis_ * 1000 * 1000);
240
241 // Now try to Wait.
242 Monitor::Wait(self, monitor_test_->object_.Get(), 10, 0, true,
243 ThreadState::kTimedWaiting);
244
245 // No check here, as depending on scheduling we may or may not fail.
246 if (self->IsExceptionPending()) {
247 self->ClearException();
248 }
249 }
250
251 monitor_test_->complete_barrier_->Wait(self); // Wait for test completion.
252 }
253
254 void Finalize() {
255 delete this;
256 }
257
258 private:
259 MonitorTest* monitor_test_;
260 uint64_t initial_sleep_;
261 uint64_t millis_;
262};
263
264class WatchdogTask : public Task {
265 public:
266 explicit WatchdogTask(MonitorTest* monitor_test) : monitor_test_(monitor_test) {}
267
268 void Run(Thread* self) {
269 ScopedObjectAccess soa(self);
270
271 monitor_test_->watchdog_object_.Get()->MonitorEnter(self); // Lock the object.
272
273 monitor_test_->watchdog_object_.Get()->Wait(self, 30 * 1000, 0); // Wait for 30s, or being
274 // woken up.
275
276 monitor_test_->watchdog_object_.Get()->MonitorExit(self); // Release the lock.
277
278 if (!monitor_test_->completed_) {
279 LOG(FATAL) << "Watchdog timeout!";
280 }
281 }
282
283 void Finalize() {
284 delete this;
285 }
286
287 private:
288 MonitorTest* monitor_test_;
289};
290
291static void CommonWaitSetup(MonitorTest* test, ClassLinker* class_linker, uint64_t create_sleep,
292 int64_t c_millis, bool c_expected, bool interrupt, uint64_t use_sleep,
293 int64_t u_millis, bool u_expected, const char* pool_name) {
Mathieu Chartiered150002015-08-28 11:16:54 -0700294 Thread* const self = Thread::Current();
295 ScopedObjectAccess soa(self);
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700296 // First create the object we lock. String is easiest.
Mathieu Chartiered150002015-08-28 11:16:54 -0700297 StackHandleScope<3> hs(soa.Self());
298 test->object_ = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "hello, world!"));
299 test->watchdog_object_ = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self,
300 "hello, world!"));
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700301
302 // Create the barrier used to synchronize.
303 test->barrier_ = std::unique_ptr<Barrier>(new Barrier(2));
304 test->complete_barrier_ = std::unique_ptr<Barrier>(new Barrier(3));
305 test->completed_ = false;
306
307 // Fill the heap.
308 std::unique_ptr<StackHandleScope<kMaxHandles>> hsp;
Andreas Gampe5a4b8a22014-09-11 08:30:08 -0700309 std::vector<MutableHandle<mirror::Object>> handles;
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700310
Mathieu Chartiered150002015-08-28 11:16:54 -0700311 // Our job: Fill the heap, then try Wait.
312 FillHeap(soa.Self(), class_linker, &hsp, &handles);
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700313
Mathieu Chartiered150002015-08-28 11:16:54 -0700314 // Now release everything.
315 for (MutableHandle<mirror::Object>& h : handles) {
316 h.Assign(nullptr);
317 }
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700318
Mathieu Chartiered150002015-08-28 11:16:54 -0700319 // Need to drop the mutator lock to allow barriers.
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700320 ScopedThreadSuspension sts(soa.Self(), kNative);
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700321 ThreadPool thread_pool(pool_name, 3);
322 thread_pool.AddTask(self, new CreateTask(test, create_sleep, c_millis, c_expected));
323 if (interrupt) {
324 thread_pool.AddTask(self, new InterruptTask(test, use_sleep, static_cast<uint64_t>(u_millis)));
325 } else {
326 thread_pool.AddTask(self, new UseTask(test, use_sleep, u_millis, u_expected));
327 }
328 thread_pool.AddTask(self, new WatchdogTask(test));
329 thread_pool.StartWorkers(self);
330
331 // Wait on completion barrier.
Mathieu Chartiered150002015-08-28 11:16:54 -0700332 test->complete_barrier_->Wait(self);
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700333 test->completed_ = true;
334
335 // Wake the watchdog.
336 {
Mathieu Chartiered150002015-08-28 11:16:54 -0700337 ScopedObjectAccess soa2(self);
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700338 test->watchdog_object_.Get()->MonitorEnter(self); // Lock the object.
339 test->watchdog_object_.Get()->NotifyAll(self); // Wake up waiting parties.
340 test->watchdog_object_.Get()->MonitorExit(self); // Release the lock.
341 }
342
343 thread_pool.StopWorkers(self);
344}
345
346
347// First test: throwing an exception when trying to wait in Monitor with another thread.
348TEST_F(MonitorTest, CheckExceptionsWait1) {
349 // Make the CreateTask wait 10ms, the UseTask wait 10ms.
350 // => The use task will get the lock first and get to self == owner check.
Andreas Gampe369810a2015-01-14 19:53:31 -0800351 // This will lead to OOM and monitor error messages in the log.
352 ScopedLogSeverity sls(LogSeverity::FATAL);
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700353 CommonWaitSetup(this, class_linker_, 10, 50, false, false, 2, 50, true,
354 "Monitor test thread pool 1");
355}
356
357// Second test: throwing an exception for invalid wait time.
358TEST_F(MonitorTest, CheckExceptionsWait2) {
359 // Make the CreateTask wait 0ms, the UseTask wait 10ms.
360 // => The create task will get the lock first and get to ms >= 0
Andreas Gampe369810a2015-01-14 19:53:31 -0800361 // This will lead to OOM and monitor error messages in the log.
362 ScopedLogSeverity sls(LogSeverity::FATAL);
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700363 CommonWaitSetup(this, class_linker_, 0, -1, true, false, 10, 50, true,
364 "Monitor test thread pool 2");
365}
366
367// Third test: throwing an interrupted-exception.
368TEST_F(MonitorTest, CheckExceptionsWait3) {
369 // Make the CreateTask wait 0ms, then Wait for a long time. Make the InterruptTask wait 10ms,
370 // after which it will interrupt the create task and then wait another 10ms.
371 // => The create task will get to the interrupted-exception throw.
Andreas Gampe369810a2015-01-14 19:53:31 -0800372 // This will lead to OOM and monitor error messages in the log.
373 ScopedLogSeverity sls(LogSeverity::FATAL);
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700374 CommonWaitSetup(this, class_linker_, 0, 500, true, true, 10, 50, true,
375 "Monitor test thread pool 3");
376}
377
Mathieu Chartier23da0262016-07-29 16:26:01 -0700378class TryLockTask : public Task {
379 public:
380 explicit TryLockTask(Handle<mirror::Object> obj) : obj_(obj) {}
381
382 void Run(Thread* self) {
383 ScopedObjectAccess soa(self);
384 // Lock is held by other thread, try lock should fail.
385 ObjectTryLock<mirror::Object> lock(self, obj_);
386 EXPECT_FALSE(lock.Acquired());
387 }
388
389 void Finalize() {
390 delete this;
391 }
392
393 private:
394 Handle<mirror::Object> obj_;
395};
396
397// Test trylock in deadlock scenarios.
398TEST_F(MonitorTest, TestTryLock) {
399 ScopedLogSeverity sls(LogSeverity::FATAL);
400
401 Thread* const self = Thread::Current();
402 ThreadPool thread_pool("the pool", 2);
403 ScopedObjectAccess soa(self);
404 StackHandleScope<3> hs(self);
405 Handle<mirror::Object> obj1(
406 hs.NewHandle<mirror::Object>(mirror::String::AllocFromModifiedUtf8(self, "hello, world!")));
407 Handle<mirror::Object> obj2(
408 hs.NewHandle<mirror::Object>(mirror::String::AllocFromModifiedUtf8(self, "hello, world!")));
409 {
410 ObjectLock<mirror::Object> lock1(self, obj1);
411 ObjectLock<mirror::Object> lock2(self, obj1);
412 {
413 ObjectTryLock<mirror::Object> trylock(self, obj1);
414 EXPECT_TRUE(trylock.Acquired());
415 }
416 // Test failure case.
417 thread_pool.AddTask(self, new TryLockTask(obj1));
418 thread_pool.StartWorkers(self);
419 ScopedThreadSuspension sts(self, kSuspended);
420 thread_pool.Wait(Thread::Current(), /*do_work*/false, /*may_hold_locks*/false);
421 }
422 // Test that the trylock actually locks the object.
423 {
424 ObjectTryLock<mirror::Object> trylock(self, obj1);
425 EXPECT_TRUE(trylock.Acquired());
426 obj1->Notify(self);
427 // Since we hold the lock there should be no monitor state exeception.
428 self->AssertNoPendingException();
429 }
430 thread_pool.StopWorkers(self);
431}
432
433
Elena Sayapina1af6a1f2014-06-20 16:58:37 +0700434} // namespace art