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