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