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 31 namespace art { 32 33 class 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. 58 static const size_t kMaxHandles = 1000000; // Use arbitrary large amount for now. 59 static 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 106 class 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 181 class 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 220 class 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 263 class 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 290 static 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. 357 TEST_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. 365 TEST_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. 373 TEST_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