OSDN Git Service

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