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