OSDN Git Service

Revert "Revert "Use try lock to fix class resolution race""
[android-x86/art.git] / runtime / monitor_test.cc
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 "barrier.h"
18 #include "monitor.h"
19
20 #include <string>
21
22 #include "atomic.h"
23 #include "base/time_utils.h"
24 #include "class_linker-inl.h"
25 #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
29 #include "object_lock.h"
30 #include "scoped_thread_state_change.h"
31 #include "thread_pool.h"
32
33 namespace art {
34
35 class MonitorTest : public CommonRuntimeTest {
36  protected:
37   void SetUpRuntimeOptions(RuntimeOptions *options) OVERRIDE {
38     // 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.
60 static const size_t kMaxHandles = 1000000;  // Use arbitrary large amount for now.
61 static void FillHeap(Thread* self, ClassLinker* class_linker,
62                      std::unique_ptr<StackHandleScope<kMaxHandles>>* hsp,
63                      std::vector<MutableHandle<mirror::Object>>* handles)
64     SHARED_REQUIRES(Locks::mutator_lock_) {
65   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) {
78     MutableHandle<mirror::Object> h((*hsp)->NewHandle<mirror::Object>(
79         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()) {
97     MutableHandle<mirror::Object> h = (*hsp)->NewHandle<mirror::Object>(c->AllocObject(self));
98     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
108 class CreateTask : public Task {
109  public:
110   CreateTask(MonitorTest* monitor_test, uint64_t initial_sleep, int64_t millis, bool expected) :
111       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.
119       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.
121       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
182 class 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
221 class 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
264 class 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
291 static 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) {
294   Thread* const self = Thread::Current();
295   ScopedObjectAccess soa(self);
296   // First create the object we lock. String is easiest.
297   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!"));
301
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;
309   std::vector<MutableHandle<mirror::Object>> handles;
310
311   // Our job: Fill the heap, then try Wait.
312   FillHeap(soa.Self(), class_linker, &hsp, &handles);
313
314   // Now release everything.
315   for (MutableHandle<mirror::Object>& h : handles) {
316     h.Assign(nullptr);
317   }
318
319   // Need to drop the mutator lock to allow barriers.
320   ScopedThreadSuspension sts(soa.Self(), kNative);
321   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.
332   test->complete_barrier_->Wait(self);
333   test->completed_ = true;
334
335   // Wake the watchdog.
336   {
337     ScopedObjectAccess soa2(self);
338     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.
348 TEST_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.
351   // This will lead to OOM and monitor error messages in the log.
352   ScopedLogSeverity sls(LogSeverity::FATAL);
353   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.
358 TEST_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
361   // This will lead to OOM and monitor error messages in the log.
362   ScopedLogSeverity sls(LogSeverity::FATAL);
363   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.
368 TEST_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.
372   // This will lead to OOM and monitor error messages in the log.
373   ScopedLogSeverity sls(LogSeverity::FATAL);
374   CommonWaitSetup(this, class_linker_, 0, 500, true, true, 10, 50, true,
375                   "Monitor test thread pool 3");
376 }
377
378 class 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.
398 TEST_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
434 }  // namespace art