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