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