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