• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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