11af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina/*
21af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina * Copyright (C) 2014 The Android Open Source Project
31af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina *
41af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina * Licensed under the Apache License, Version 2.0 (the "License");
51af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina * you may not use this file except in compliance with the License.
61af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina * You may obtain a copy of the License at
71af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina *
81af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina *      http://www.apache.org/licenses/LICENSE-2.0
91af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina *
101af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina * Unless required by applicable law or agreed to in writing, software
111af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina * distributed under the License is distributed on an "AS IS" BASIS,
121af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina * See the License for the specific language governing permissions and
141af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina * limitations under the License.
151af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina */
161af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
171af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina#include "barrier.h"
181af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina#include "monitor.h"
191af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
201af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina#include <string>
211af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
221af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina#include "atomic.h"
2380afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "base/time_utils.h"
243481ba2c4e4f3aa80d8c6d50a9f85dacb56b508bVladimir Marko#include "class_linker-inl.h"
251af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina#include "common_runtime_test.h"
261af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina#include "handle_scope-inl.h"
271af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina#include "mirror/class-inl.h"
281af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina#include "mirror/string-inl.h"  // Strings are easiest to allocate
2923da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier#include "object_lock.h"
30e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "scoped_thread_state_change.h"
311af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina#include "thread_pool.h"
321af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
331af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapinanamespace art {
341af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
351af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapinaclass MonitorTest : public CommonRuntimeTest {
361af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina protected:
37e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers  void SetUpRuntimeOptions(RuntimeOptions *options) OVERRIDE {
381af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    // Use a smaller heap
391af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    for (std::pair<std::string, const void*>& pair : *options) {
401af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      if (pair.first.find("-Xmx") == 0) {
411af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina        pair.first = "-Xmx4M";  // Smallest we can go.
421af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      }
431af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    }
441af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    options->push_back(std::make_pair("-Xint", nullptr));
451af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  }
461af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina public:
471af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  std::unique_ptr<Monitor> monitor_;
481af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  Handle<mirror::String> object_;
491af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  Handle<mirror::String> second_object_;
501af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  Handle<mirror::String> watchdog_object_;
511af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  // One exception test is for waiting on another Thread's lock. This is used to race-free &
521af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  // loop-free pass
531af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  Thread* thread_;
541af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  std::unique_ptr<Barrier> barrier_;
551af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  std::unique_ptr<Barrier> complete_barrier_;
561af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  bool completed_;
571af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina};
581af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
591af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina// Fill the heap.
601af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapinastatic const size_t kMaxHandles = 1000000;  // Use arbitrary large amount for now.
611af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapinastatic void FillHeap(Thread* self, ClassLinker* class_linker,
621af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina                     std::unique_ptr<StackHandleScope<kMaxHandles>>* hsp,
635a4b8a236030460651a3136397d23ca6744e7eb7Andreas Gampe                     std::vector<MutableHandle<mirror::Object>>* handles)
6490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier    SHARED_REQUIRES(Locks::mutator_lock_) {
651af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  Runtime::Current()->GetHeap()->SetIdealFootprint(1 * GB);
661af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
671af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  hsp->reset(new StackHandleScope<kMaxHandles>(self));
681af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  // Class java.lang.Object.
691af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  Handle<mirror::Class> c((*hsp)->NewHandle(class_linker->FindSystemClass(self,
701af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina                                                                       "Ljava/lang/Object;")));
711af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  // Array helps to fill memory faster.
721af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  Handle<mirror::Class> ca((*hsp)->NewHandle(class_linker->FindSystemClass(self,
731af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina                                                                        "[Ljava/lang/Object;")));
741af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
751af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  // Start allocating with 128K
761af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  size_t length = 128 * KB / 4;
771af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  while (length > 10) {
785a4b8a236030460651a3136397d23ca6744e7eb7Andreas Gampe    MutableHandle<mirror::Object> h((*hsp)->NewHandle<mirror::Object>(
791af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina        mirror::ObjectArray<mirror::Object>::Alloc(self, ca.Get(), length / 4)));
801af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    if (self->IsExceptionPending() || h.Get() == nullptr) {
811af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      self->ClearException();
821af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
831af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      // Try a smaller length
841af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      length = length / 8;
851af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      // Use at most half the reported free space.
861af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      size_t mem = Runtime::Current()->GetHeap()->GetFreeMemory();
871af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      if (length * 8 > mem) {
881af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina        length = mem / 8;
891af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      }
901af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    } else {
911af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      handles->push_back(h);
921af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    }
931af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  }
941af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
951af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  // Allocate simple objects till it fails.
961af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  while (!self->IsExceptionPending()) {
975a4b8a236030460651a3136397d23ca6744e7eb7Andreas Gampe    MutableHandle<mirror::Object> h = (*hsp)->NewHandle<mirror::Object>(c->AllocObject(self));
981af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    if (!self->IsExceptionPending() && h.Get() != nullptr) {
991af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      handles->push_back(h);
1001af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    }
1011af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  }
1021af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  self->ClearException();
1031af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina}
1041af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1051af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina// Check that an exception can be thrown correctly.
1061af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina// This test is potentially racy, but the timeout is long enough that it should work.
1071af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1081af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapinaclass CreateTask : public Task {
1091af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina public:
1103887c468d731420e929e6ad3acf190d5431e94fcRoland Levillain  CreateTask(MonitorTest* monitor_test, uint64_t initial_sleep, int64_t millis, bool expected) :
1111af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      monitor_test_(monitor_test), initial_sleep_(initial_sleep), millis_(millis),
1121af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      expected_(expected) {}
1131af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1141af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  void Run(Thread* self) {
1151af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    {
1161af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      ScopedObjectAccess soa(self);
1171af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1181af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      monitor_test_->thread_ = self;        // Pass the Thread.
1192cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier      monitor_test_->object_.Get()->MonitorEnter(self);  // Lock the object. This should transition
1202cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier      LockWord lock_after = monitor_test_->object_.Get()->GetLockWord(false);  // it to thinLocked.
1211af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      LockWord::LockState new_state = lock_after.GetState();
1221af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1231af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      // Cannot use ASSERT only, as analysis thinks we'll keep holding the mutex.
1241af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      if (LockWord::LockState::kThinLocked != new_state) {
1251af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina        monitor_test_->object_.Get()->MonitorExit(self);         // To appease analysis.
1261af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina        ASSERT_EQ(LockWord::LockState::kThinLocked, new_state);  // To fail the test.
1271af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina        return;
1281af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      }
1291af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1301af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      // Force a fat lock by running identity hashcode to fill up lock word.
1311af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      monitor_test_->object_.Get()->IdentityHashCode();
1321af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      LockWord lock_after2 = monitor_test_->object_.Get()->GetLockWord(false);
1331af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      LockWord::LockState new_state2 = lock_after2.GetState();
1341af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1351af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      // Cannot use ASSERT only, as analysis thinks we'll keep holding the mutex.
1361af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      if (LockWord::LockState::kFatLocked != new_state2) {
1371af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina        monitor_test_->object_.Get()->MonitorExit(self);         // To appease analysis.
1381af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina        ASSERT_EQ(LockWord::LockState::kFatLocked, new_state2);  // To fail the test.
1391af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina        return;
1401af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      }
1411af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    }  // Need to drop the mutator lock to use the barrier.
1421af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1431af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    monitor_test_->barrier_->Wait(self);           // Let the other thread know we're done.
1441af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1451af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    {
1461af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      ScopedObjectAccess soa(self);
1471af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1481af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      // Give the other task a chance to do its thing.
1491af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      NanoSleep(initial_sleep_ * 1000 * 1000);
1501af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1511af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      // Now try to Wait on the Monitor.
1521af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      Monitor::Wait(self, monitor_test_->object_.Get(), millis_, 0, true,
1531af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina                    ThreadState::kTimedWaiting);
1541af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1551af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      // Check the exception status against what we expect.
1561af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      EXPECT_EQ(expected_, self->IsExceptionPending());
1571af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      if (expected_) {
1581af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina        self->ClearException();
1591af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      }
1601af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    }
1611af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1621af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    monitor_test_->complete_barrier_->Wait(self);  // Wait for test completion.
1631af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1641af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    {
1651af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      ScopedObjectAccess soa(self);
1661af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      monitor_test_->object_.Get()->MonitorExit(self);  // Release the object. Appeases analysis.
1671af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    }
1681af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  }
1691af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1701af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  void Finalize() {
1711af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    delete this;
1721af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  }
1731af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1741af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina private:
1751af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  MonitorTest* monitor_test_;
1761af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  uint64_t initial_sleep_;
1771af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  int64_t millis_;
1781af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  bool expected_;
1791af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina};
1801af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1811af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1821af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapinaclass UseTask : public Task {
1831af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina public:
1841af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  UseTask(MonitorTest* monitor_test, uint64_t initial_sleep, int64_t millis, bool expected) :
1851af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      monitor_test_(monitor_test), initial_sleep_(initial_sleep), millis_(millis),
1861af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      expected_(expected) {}
1871af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1881af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  void Run(Thread* self) {
1891af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    monitor_test_->barrier_->Wait(self);  // Wait for the other thread to set up the monitor.
1901af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1911af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    {
1921af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      ScopedObjectAccess soa(self);
1931af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1941af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      // Give the other task a chance to do its thing.
1951af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      NanoSleep(initial_sleep_ * 1000 * 1000);
1961af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
1971af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      Monitor::Wait(self, monitor_test_->object_.Get(), millis_, 0, true,
1981af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina                    ThreadState::kTimedWaiting);
1991af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2001af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      // Check the exception status against what we expect.
2011af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      EXPECT_EQ(expected_, self->IsExceptionPending());
2021af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      if (expected_) {
2031af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina        self->ClearException();
2041af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      }
2051af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    }
2061af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2071af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    monitor_test_->complete_barrier_->Wait(self);  // Wait for test completion.
2081af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  }
2091af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2101af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  void Finalize() {
2111af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    delete this;
2121af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  }
2131af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2141af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina private:
2151af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  MonitorTest* monitor_test_;
2161af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  uint64_t initial_sleep_;
2171af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  int64_t millis_;
2181af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  bool expected_;
2191af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina};
2201af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2211af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapinaclass InterruptTask : public Task {
2221af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina public:
2231af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  InterruptTask(MonitorTest* monitor_test, uint64_t initial_sleep, uint64_t millis) :
2241af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      monitor_test_(monitor_test), initial_sleep_(initial_sleep), millis_(millis) {}
2251af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2261af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  void Run(Thread* self) {
2271af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    monitor_test_->barrier_->Wait(self);  // Wait for the other thread to set up the monitor.
2281af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2291af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    {
2301af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      ScopedObjectAccess soa(self);
2311af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2321af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      // Give the other task a chance to do its thing.
2331af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      NanoSleep(initial_sleep_ * 1000 * 1000);
2341af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2351af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      // Interrupt the other thread.
2361af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      monitor_test_->thread_->Interrupt(self);
2371af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2381af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      // Give it some more time to get to the exception code.
2391af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      NanoSleep(millis_ * 1000 * 1000);
2401af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2411af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      // Now try to Wait.
2421af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      Monitor::Wait(self, monitor_test_->object_.Get(), 10, 0, true,
2431af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina                    ThreadState::kTimedWaiting);
2441af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2451af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      // No check here, as depending on scheduling we may or may not fail.
2461af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      if (self->IsExceptionPending()) {
2471af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina        self->ClearException();
2481af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      }
2491af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    }
2501af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2511af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    monitor_test_->complete_barrier_->Wait(self);  // Wait for test completion.
2521af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  }
2531af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2541af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  void Finalize() {
2551af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    delete this;
2561af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  }
2571af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2581af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina private:
2591af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  MonitorTest* monitor_test_;
2601af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  uint64_t initial_sleep_;
2611af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  uint64_t millis_;
2621af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina};
2631af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2641af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapinaclass WatchdogTask : public Task {
2651af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina public:
2661af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  explicit WatchdogTask(MonitorTest* monitor_test) : monitor_test_(monitor_test) {}
2671af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2681af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  void Run(Thread* self) {
2691af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    ScopedObjectAccess soa(self);
2701af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2711af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    monitor_test_->watchdog_object_.Get()->MonitorEnter(self);        // Lock the object.
2721af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2731af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    monitor_test_->watchdog_object_.Get()->Wait(self, 30 * 1000, 0);  // Wait for 30s, or being
2741af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina                                                                      // woken up.
2751af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2761af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    monitor_test_->watchdog_object_.Get()->MonitorExit(self);         // Release the lock.
2771af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2781af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    if (!monitor_test_->completed_) {
2791af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina      LOG(FATAL) << "Watchdog timeout!";
2801af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    }
2811af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  }
2821af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2831af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  void Finalize() {
2841af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    delete this;
2851af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  }
2861af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2871af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina private:
2881af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  MonitorTest* monitor_test_;
2891af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina};
2901af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
2911af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapinastatic void CommonWaitSetup(MonitorTest* test, ClassLinker* class_linker, uint64_t create_sleep,
2921af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina                            int64_t c_millis, bool c_expected, bool interrupt, uint64_t use_sleep,
2931af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina                            int64_t u_millis, bool u_expected, const char* pool_name) {
294ed15000a5099f5e230c8ded5ac75692bae272650Mathieu Chartier  Thread* const self = Thread::Current();
295ed15000a5099f5e230c8ded5ac75692bae272650Mathieu Chartier  ScopedObjectAccess soa(self);
2961af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  // First create the object we lock. String is easiest.
297ed15000a5099f5e230c8ded5ac75692bae272650Mathieu Chartier  StackHandleScope<3> hs(soa.Self());
298ed15000a5099f5e230c8ded5ac75692bae272650Mathieu Chartier  test->object_ = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "hello, world!"));
299ed15000a5099f5e230c8ded5ac75692bae272650Mathieu Chartier  test->watchdog_object_ = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self,
300ed15000a5099f5e230c8ded5ac75692bae272650Mathieu Chartier                                                                              "hello, world!"));
3011af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
3021af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  // Create the barrier used to synchronize.
3031af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  test->barrier_ = std::unique_ptr<Barrier>(new Barrier(2));
3041af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  test->complete_barrier_ = std::unique_ptr<Barrier>(new Barrier(3));
3051af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  test->completed_ = false;
3061af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
3071af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  // Fill the heap.
3081af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  std::unique_ptr<StackHandleScope<kMaxHandles>> hsp;
3095a4b8a236030460651a3136397d23ca6744e7eb7Andreas Gampe  std::vector<MutableHandle<mirror::Object>> handles;
3101af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
311ed15000a5099f5e230c8ded5ac75692bae272650Mathieu Chartier  // Our job: Fill the heap, then try Wait.
312ed15000a5099f5e230c8ded5ac75692bae272650Mathieu Chartier  FillHeap(soa.Self(), class_linker, &hsp, &handles);
3131af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
314ed15000a5099f5e230c8ded5ac75692bae272650Mathieu Chartier  // Now release everything.
315ed15000a5099f5e230c8ded5ac75692bae272650Mathieu Chartier  for (MutableHandle<mirror::Object>& h : handles) {
316ed15000a5099f5e230c8ded5ac75692bae272650Mathieu Chartier    h.Assign(nullptr);
317ed15000a5099f5e230c8ded5ac75692bae272650Mathieu Chartier  }
3181af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
319ed15000a5099f5e230c8ded5ac75692bae272650Mathieu Chartier  // Need to drop the mutator lock to allow barriers.
320f1d666e1b48f8070ef1177fce156c08827f08eb8Mathieu Chartier  ScopedThreadSuspension sts(soa.Self(), kNative);
3211af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  ThreadPool thread_pool(pool_name, 3);
3221af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  thread_pool.AddTask(self, new CreateTask(test, create_sleep, c_millis, c_expected));
3231af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  if (interrupt) {
3241af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    thread_pool.AddTask(self, new InterruptTask(test, use_sleep, static_cast<uint64_t>(u_millis)));
3251af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  } else {
3261af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    thread_pool.AddTask(self, new UseTask(test, use_sleep, u_millis, u_expected));
3271af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  }
3281af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  thread_pool.AddTask(self, new WatchdogTask(test));
3291af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  thread_pool.StartWorkers(self);
3301af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
3311af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  // Wait on completion barrier.
332ed15000a5099f5e230c8ded5ac75692bae272650Mathieu Chartier  test->complete_barrier_->Wait(self);
3331af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  test->completed_ = true;
3341af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
3351af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  // Wake the watchdog.
3361af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  {
337ed15000a5099f5e230c8ded5ac75692bae272650Mathieu Chartier    ScopedObjectAccess soa2(self);
3381af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    test->watchdog_object_.Get()->MonitorEnter(self);     // Lock the object.
3391af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    test->watchdog_object_.Get()->NotifyAll(self);        // Wake up waiting parties.
3401af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina    test->watchdog_object_.Get()->MonitorExit(self);      // Release the lock.
3411af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  }
3421af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
3431af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  thread_pool.StopWorkers(self);
3441af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina}
3451af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
3461af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
3471af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina// First test: throwing an exception when trying to wait in Monitor with another thread.
3481af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena SayapinaTEST_F(MonitorTest, CheckExceptionsWait1) {
3491af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  // Make the CreateTask wait 10ms, the UseTask wait 10ms.
3501af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  // => The use task will get the lock first and get to self == owner check.
351369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // This will lead to OOM and monitor error messages in the log.
352369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  ScopedLogSeverity sls(LogSeverity::FATAL);
3531af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  CommonWaitSetup(this, class_linker_, 10, 50, false, false, 2, 50, true,
3541af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina                  "Monitor test thread pool 1");
3551af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina}
3561af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
3571af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina// Second test: throwing an exception for invalid wait time.
3581af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena SayapinaTEST_F(MonitorTest, CheckExceptionsWait2) {
3591af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  // Make the CreateTask wait 0ms, the UseTask wait 10ms.
3601af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  // => The create task will get the lock first and get to ms >= 0
361369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // This will lead to OOM and monitor error messages in the log.
362369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  ScopedLogSeverity sls(LogSeverity::FATAL);
3631af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  CommonWaitSetup(this, class_linker_, 0, -1, true, false, 10, 50, true,
3641af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina                  "Monitor test thread pool 2");
3651af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina}
3661af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
3671af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina// Third test: throwing an interrupted-exception.
3681af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena SayapinaTEST_F(MonitorTest, CheckExceptionsWait3) {
3691af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  // Make the CreateTask wait 0ms, then Wait for a long time. Make the InterruptTask wait 10ms,
3701af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  // after which it will interrupt the create task and then wait another 10ms.
3711af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  // => The create task will get to the interrupted-exception throw.
372369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  // This will lead to OOM and monitor error messages in the log.
373369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe  ScopedLogSeverity sls(LogSeverity::FATAL);
3741af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina  CommonWaitSetup(this, class_linker_, 0, 500, true, true, 10, 50, true,
3751af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina                  "Monitor test thread pool 3");
3761af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina}
3771af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina
37823da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartierclass TryLockTask : public Task {
37923da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier public:
38023da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  explicit TryLockTask(Handle<mirror::Object> obj) : obj_(obj) {}
38123da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier
38223da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  void Run(Thread* self) {
38323da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    ScopedObjectAccess soa(self);
38423da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    // Lock is held by other thread, try lock should fail.
38523da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    ObjectTryLock<mirror::Object> lock(self, obj_);
38623da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    EXPECT_FALSE(lock.Acquired());
38723da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  }
38823da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier
38923da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  void Finalize() {
39023da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    delete this;
39123da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  }
39223da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier
39323da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier private:
39423da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  Handle<mirror::Object> obj_;
39523da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier};
39623da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier
39723da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier// Test trylock in deadlock scenarios.
39823da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu ChartierTEST_F(MonitorTest, TestTryLock) {
39923da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  ScopedLogSeverity sls(LogSeverity::FATAL);
40023da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier
40123da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  Thread* const self = Thread::Current();
40223da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  ThreadPool thread_pool("the pool", 2);
40323da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  ScopedObjectAccess soa(self);
40423da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  StackHandleScope<3> hs(self);
40523da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  Handle<mirror::Object> obj1(
40623da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier      hs.NewHandle<mirror::Object>(mirror::String::AllocFromModifiedUtf8(self, "hello, world!")));
40723da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  Handle<mirror::Object> obj2(
40823da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier      hs.NewHandle<mirror::Object>(mirror::String::AllocFromModifiedUtf8(self, "hello, world!")));
40923da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  {
41023da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    ObjectLock<mirror::Object> lock1(self, obj1);
41123da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    ObjectLock<mirror::Object> lock2(self, obj1);
41223da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    {
41323da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier      ObjectTryLock<mirror::Object> trylock(self, obj1);
41423da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier      EXPECT_TRUE(trylock.Acquired());
41523da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    }
41623da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    // Test failure case.
41723da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    thread_pool.AddTask(self, new TryLockTask(obj1));
41823da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    thread_pool.StartWorkers(self);
41923da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    ScopedThreadSuspension sts(self, kSuspended);
42023da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    thread_pool.Wait(Thread::Current(), /*do_work*/false, /*may_hold_locks*/false);
42123da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  }
42223da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  // Test that the trylock actually locks the object.
42323da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  {
42423da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    ObjectTryLock<mirror::Object> trylock(self, obj1);
42523da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    EXPECT_TRUE(trylock.Acquired());
42623da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    obj1->Notify(self);
42723da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    // Since we hold the lock there should be no monitor state exeception.
42823da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier    self->AssertNoPendingException();
42923da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  }
43023da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  thread_pool.StopWorkers(self);
43123da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier}
43223da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier
43323da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier
4341af6a1fa35ff7dc0a5c653f19dbc8a91c914aa42Elena Sayapina}  // namespace art
435